home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / Sources / Sprite.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  65.7 KB  |  2,425 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    Sprite.c
  3. //
  4. //    Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  5. //
  6. //    Description:    implementation of the sprites
  7. ///--------------------------------------------------------------------------------------
  8.  
  9. #ifndef __MEMORY__
  10. #include <Memory.h>
  11. #endif
  12.  
  13. #ifndef __RESOURCES__
  14. #include <Resources.h>
  15. #endif
  16.  
  17. #ifndef __SWCOMMON__
  18. #include <SWCommonHeaders.h>
  19. #endif
  20.  
  21. #ifndef __SPRITEWORLDUTILS__
  22. #include <SpriteWorldUtils.h>
  23. #endif
  24.  
  25. #ifndef __SPRITEWORLD__
  26. #include <SpriteWorld.h>
  27. #endif
  28.  
  29. #ifndef __SPRITE__
  30. #include <Sprite.h>
  31. #endif
  32.  
  33. #ifndef __SPRITEFRAME__
  34. #include <SpriteFrame.h>
  35. #endif
  36.  
  37. #ifndef __SPRITECOMPILER__
  38. #include <SpriteCompiler.h>
  39. #endif
  40.  
  41. #ifndef __BLITPIXIEINTERFACE__
  42. #include <BlitPixieInterface.h>
  43. #endif
  44.  
  45. #include <BlitPixieHeader.h>
  46.  
  47. static void CalcMaxWidthHeight( 
  48.     RectArrayPtr newRectArrayP, 
  49.     short *maxWidthP, 
  50.     short *maxHeightP );
  51.  
  52. ///--------------------------------------------------------------------------------------
  53. //    SWCreateSprite
  54. ///--------------------------------------------------------------------------------------
  55.  
  56. SW_FUNC OSErr SWCreateSprite(
  57.     SpritePtr* newSpriteP,
  58.     void* spriteStorageP,
  59.     short maxFrames)
  60. {
  61.     OSErr err = noErr;
  62.     SpritePtr tempSpriteP;
  63.     Size frameArraySize;
  64.  
  65.     *newSpriteP = NULL;
  66.  
  67.     tempSpriteP =  (spriteStorageP == NULL) ? (SpritePtr)NewPtr(sizeof(SpriteRec)) : (SpritePtr)spriteStorageP;
  68.  
  69.     if (tempSpriteP != NULL)
  70.     {
  71.         frameArraySize = (Size)maxFrames * sizeof(FramePtr);
  72.  
  73.         tempSpriteP->frameArray = (FramePtr *)NewPtrClear(frameArraySize);
  74.  
  75.         if (tempSpriteP->frameArray != NULL)
  76.         {
  77.             tempSpriteP->parentSpriteLayerP = NULL;
  78.             tempSpriteP->nextSpriteP = NULL;
  79.             tempSpriteP->prevSpriteP = NULL;
  80.  
  81.                 // initialize drawing fields
  82.             tempSpriteP->isVisible = true;
  83.             tempSpriteP->needsToBeDrawn = true;
  84.             tempSpriteP->needsToBeErased = false;
  85.             tempSpriteP->destFrameRect.left = 0;
  86.             tempSpriteP->destFrameRect.top = 0;
  87.             tempSpriteP->destFrameRect.right = 0;
  88.             tempSpriteP->destFrameRect.bottom = 0;
  89.             tempSpriteP->oldFrameRect.left = 0;
  90.             tempSpriteP->oldFrameRect.top = 0;
  91.             tempSpriteP->oldFrameRect.right = 0;
  92.             tempSpriteP->oldFrameRect.bottom = 0;
  93.             tempSpriteP->deltaFrameRect.left = 0;
  94.             tempSpriteP->deltaFrameRect.top = 0;
  95.             tempSpriteP->deltaFrameRect.right = 0;
  96.             tempSpriteP->deltaFrameRect.bottom = 0;
  97.             tempSpriteP->frameDrawProc = SWStdSpriteDrawProc;
  98.             tempSpriteP->tileDepth = 1;
  99.                 
  100.                 // initialize drawing fields for scrolling routines
  101.             tempSpriteP->destOffscreenRect.left = 0;
  102.             tempSpriteP->destOffscreenRect.top = 0;
  103.             tempSpriteP->destOffscreenRect.right = 0;
  104.             tempSpriteP->destOffscreenRect.bottom = 0;
  105.             tempSpriteP->oldRectIsVisible = false;
  106.  
  107.                 // initialize frame fields
  108.             tempSpriteP->curFrameP = NULL;
  109.             tempSpriteP->numFrames = 0;
  110.             tempSpriteP->maxFrames = maxFrames;
  111.             tempSpriteP->frameTimeInterval = -1;
  112.             tempSpriteP->timeOfLastFrameChange = 0;
  113.             tempSpriteP->frameAdvance = 1;
  114.             tempSpriteP->curFrameIndex = 0;
  115.             tempSpriteP->firstFrameIndex = 0;
  116.             tempSpriteP->lastFrameIndex = 0;
  117.             tempSpriteP->frameChangeProc = NULL;
  118.  
  119.                 // initialize movement fields
  120.             tempSpriteP->moveTimeInterval = 0;
  121.             tempSpriteP->timeOfLastMove = 0;
  122.             tempSpriteP->horizMoveDelta = 0;
  123.             tempSpriteP->vertMoveDelta = 0;
  124.             tempSpriteP->moveBoundsRect.left = 0;
  125.             tempSpriteP->moveBoundsRect.top = 0;
  126.             tempSpriteP->moveBoundsRect.right = 0;
  127.             tempSpriteP->moveBoundsRect.bottom = 0;
  128.             tempSpriteP->spriteMoveProc = SWTempSpriteMoveProc;
  129.             tempSpriteP->realSpriteMoveProc = NULL;
  130.             
  131.             tempSpriteP->spriteCollideProc = NULL;
  132.             
  133.             tempSpriteP->sharedPictGWorld = NULL;
  134.             tempSpriteP->sharedMaskGWorld = NULL;
  135.             tempSpriteP->spriteRemoval = kSWDontRemoveSprite;
  136.             tempSpriteP->frameAdvanceMode = kSWWrapAroundMode;
  137.             
  138.             tempSpriteP->scaledWidth = -1;
  139.             tempSpriteP->scaledHeight = -1;
  140.             
  141.             tempSpriteP->colorRGB.red = 0;
  142.             tempSpriteP->colorRGB.green = 0;
  143.             tempSpriteP->colorRGB.blue = 0;
  144.             tempSpriteP->colorValue = 0;
  145.             
  146.             tempSpriteP->flippedHorizontal = false;
  147.             tempSpriteP->flippedVertical = false;
  148.             
  149.             tempSpriteP->userData = 0;
  150.  
  151.                 // the sprite has been successfully created
  152.             *newSpriteP = tempSpriteP;
  153.         }
  154.         else
  155.         {
  156.             err = MemError();
  157.  
  158.             DisposePtr((Ptr)tempSpriteP);
  159.         }
  160.     }
  161.     else
  162.     {
  163.         err = MemError();
  164.     }
  165.  
  166.     SWSetStickyIfError( err );
  167.     return err;
  168. }
  169.  
  170.  
  171. ///--------------------------------------------------------------------------------------
  172. //    SWCreateSpriteFromCicnResource
  173. ///--------------------------------------------------------------------------------------
  174.  
  175. SW_FUNC OSErr SWCreateSpriteFromCicnResource(
  176.     SpriteWorldPtr destSpriteWorldP,
  177.     SpritePtr* newSpriteP,
  178.     void* spriteStorageP,
  179.     short cIconID,
  180.     short maxFrames,
  181.     MaskType maskType)
  182. {
  183.     OSErr             err;
  184.     SpritePtr         tempSpriteP;
  185.     FramePtr         newFrameP;
  186.     short             frame;
  187.     
  188.     SW_ASSERT(destSpriteWorldP != NULL);
  189.  
  190.     *newSpriteP = NULL;
  191.  
  192.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  193.     
  194.     if (err == noErr)
  195.     {
  196.         for (frame = 0; frame < maxFrames; frame++)
  197.         {
  198.             err = SWCreateFrameFromCicnResource(destSpriteWorldP, &newFrameP, 
  199.                     cIconID + frame, maskType);
  200.  
  201.             if (err == noErr)
  202.             {
  203.                 err = SWAddFrame(tempSpriteP, newFrameP);
  204.             }
  205.  
  206.             if (err != noErr)
  207.             {
  208.                 SWDisposeFrame(&newFrameP);
  209.                 SWDisposeSprite(&tempSpriteP);
  210.                 break;
  211.             }
  212.         }
  213.  
  214.         if (err == noErr)
  215.         {
  216.             SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  217.             SWSetCurrentFrameIndex(tempSpriteP, 0);
  218.             *newSpriteP = tempSpriteP;
  219.         }
  220.     }
  221.  
  222.     SWSetStickyIfError( err );
  223.     return err;
  224. }
  225.  
  226.  
  227. ///--------------------------------------------------------------------------------------
  228. //    SWCreateSpriteFromPictResource
  229. ///--------------------------------------------------------------------------------------
  230.  
  231. SW_FUNC OSErr SWCreateSpriteFromPictResource(
  232.     SpriteWorldPtr destSpriteWorldP,
  233.     SpritePtr* newSpriteP,
  234.     void* spriteStorageP,
  235.     short pictResID,
  236.     short maskResID,
  237.     short maxFrames,
  238.     MaskType maskType)
  239. {
  240.     OSErr             err;
  241.     SpritePtr         tempSpriteP;
  242.     FramePtr         newFrameP;
  243.     short             frame;
  244.     
  245.     SW_ASSERT(destSpriteWorldP != NULL);
  246.     
  247.     *newSpriteP = NULL;
  248.  
  249.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  250.  
  251.     if (err == noErr)
  252.     {
  253.         for (frame = 0; frame < maxFrames; frame++)
  254.         {
  255.             err = SWCreateFrameFromPictResource(destSpriteWorldP, &newFrameP, 
  256.                     pictResID + frame, maskResID + frame, maskType);
  257.  
  258.             if (err == noErr)
  259.             {
  260.                 err = SWAddFrame(tempSpriteP, newFrameP);
  261.             }
  262.  
  263.             if (err != noErr)
  264.             {
  265.                 SWDisposeFrame(&newFrameP);
  266.                 SWDisposeSprite(&tempSpriteP);
  267.                 break;
  268.             }
  269.         }
  270.  
  271.         if (err == noErr)
  272.         {
  273.             SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  274.             SWSetCurrentFrameIndex(tempSpriteP, 0);
  275.             *newSpriteP = tempSpriteP;
  276.         }
  277.     }
  278.     
  279.     SWSetStickyIfError( err );
  280.     return err;
  281. }
  282.  
  283.  
  284. ///--------------------------------------------------------------------------------------
  285. //    SWCreateSpriteFromSinglePict
  286. ///--------------------------------------------------------------------------------------
  287.  
  288. SW_FUNC OSErr SWCreateSpriteFromSinglePict(
  289.     SpriteWorldPtr destSpriteWorldP,
  290.     SpritePtr* newSpriteP,
  291.     void* spriteStorageP,
  292.     short pictResID,
  293.     short maskResID,
  294.     short frameDimension,
  295.     short borderWidth,
  296.     MaskType maskType)
  297. {
  298.     OSErr             err = noErr;
  299.     Handle            rectArrayHndl;
  300.     RectArrayPtr    newRectArrayP;
  301.     PicHandle        tempPic;
  302.     GWorldPtr        tempPictGWorldP;
  303.     GWorldPtr        tempMaskGWorldP;
  304.     GWorldPtr        tempTempMaskGWorldP;
  305.     Rect            frameRect;
  306.     Boolean            verticalStrip;
  307.     SpritePtr         tempSpriteP;
  308.     FramePtr         newFrameP;
  309.     short             maxFrames;
  310.     short             frame;
  311.     short            maxWidth, maxHeight;
  312.     Boolean            needToInvertMask;
  313.     
  314.     SW_ASSERT(destSpriteWorldP != NULL);
  315.  
  316.     tempPictGWorldP = NULL;
  317.     tempMaskGWorldP = NULL;
  318.     *newSpriteP = NULL;
  319.     rectArrayHndl = NULL;
  320.     needToInvertMask = true;
  321.     
  322.     if ( frameDimension == 0 )
  323.     {
  324.         rectArrayHndl = Get1Resource( 'nrct', pictResID );
  325.     
  326.         if ( rectArrayHndl == NULL )
  327.         {
  328.             err = MemError();
  329.             if ( err == noErr )
  330.                 err = resNotFound;
  331.         }
  332.         else
  333.         {
  334.             HLock( rectArrayHndl );
  335.             newRectArrayP = (RectArrayPtr)*rectArrayHndl;
  336.             maxFrames = newRectArrayP->numFrames;
  337.             CalcMaxWidthHeight( newRectArrayP, &maxWidth, &maxHeight );
  338.         }
  339.     }
  340.     else
  341.     {
  342.         tempPic = GetPicture( pictResID );
  343.         if ( tempPic == nil )
  344.         {
  345.             err = MemError();
  346.             if ( err == noErr )
  347.                 err = resNotFound;
  348.         }
  349.         else
  350.         {
  351.             frameRect = (**(tempPic)).picFrame;
  352.             OffsetRect( &frameRect, -frameRect.left, -frameRect.top );
  353.             ReleaseResource( (Handle)tempPic );
  354.             if ( frameRect.right-frameRect.left < frameRect.bottom-frameRect.top )
  355.             {
  356.                 verticalStrip = true;
  357.                 maxFrames = frameRect.bottom/frameDimension;
  358.                 frameRect.bottom = -borderWidth;
  359.                 maxWidth = frameRect.right-frameRect.left;
  360.                 maxHeight = frameDimension;
  361.             }
  362.             else
  363.             {
  364.                 verticalStrip = false;
  365.                 maxFrames = frameRect.right/frameDimension;
  366.                 frameRect.right = -borderWidth;
  367.                 maxWidth = frameDimension;
  368.                 maxHeight = frameRect.bottom-frameRect.top;
  369.             }
  370.         }
  371.     }
  372.     
  373.     if ( err == noErr )
  374.     {    
  375.         err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  376.         
  377.         if (err == noErr)
  378.         {
  379.                 // Create the GWorld that contains the Sprite's image.
  380.             err = SWCreateGWorldFromPictResource( destSpriteWorldP, &tempPictGWorldP, pictResID );
  381.             
  382.                 // Create the GWorld used to hold the mask. 
  383.             if ( err == noErr && maskType != kNoMask )
  384.                 err = SWCreateGWorldFromPictResource( 
  385.                     destSpriteWorldP, &tempMaskGWorldP, maskResID );
  386.             
  387.             if (err == noErr)
  388.             {
  389.                     // If this is a self-masking Sprite, create the mask based on the image.
  390.                 if ( pictResID == maskResID && tempMaskGWorldP != NULL )
  391.                 {
  392.                     err = SWCreatePixelMaskFromGWorld( tempPictGWorldP, tempMaskGWorldP, (RectPtr) NULL );
  393.                     needToInvertMask = false;
  394.                     
  395.                         // If the depth is 8-bits or less, and we need to create a region mask,
  396.                         // invert the maskGWorld so the region mask is created correctly.
  397.                     if (destSpriteWorldP->pixelDepth <= 8 && (maskType & kRegionMask) != 0 )
  398.                     {
  399.                         SWInvertGWorld(tempMaskGWorldP);
  400.                         needToInvertMask = true;
  401.                     }
  402.                 }
  403.                 else if ( (maskType & kPixelMask) != 0 )
  404.                 {
  405.                         // For Sprites that are not self-masking and have a pixel mask, we
  406.                         // should still fix the GWorld's image, in case SWTransparentColor
  407.                         // is not white, or in case the depth is 16-bits or above.
  408.                     SWFixImageGWorld( tempPictGWorldP, tempMaskGWorldP, (RectPtr) NULL );
  409.                 }
  410.             }
  411.             
  412.             if (err == noErr)
  413.             {
  414.                 err = SWCreateFrameFromGWorldAndRectStart( &tempTempMaskGWorldP, maxWidth, 
  415.                     maxHeight, maskType );
  416.             }
  417.             
  418.             if (err == noErr)
  419.             {
  420.                 for (frame = 0; frame < maxFrames; frame++)
  421.                 {
  422.                     if ( frameDimension == 0 )
  423.                     {
  424.                         frameRect = newRectArrayP->frameRects[frame];
  425.                     }
  426.                     else
  427.                     {
  428.                         if ( verticalStrip )
  429.                         {
  430.                             frameRect.top = frameRect.bottom + borderWidth;
  431.                             frameRect.bottom = frameRect.top + frameDimension;
  432.                         }
  433.                         else
  434.                         {
  435.                             frameRect.left = frameRect.right + borderWidth;
  436.                             frameRect.right = frameRect.left + frameDimension;
  437.                         }
  438.                     }
  439.                     
  440.                     err = SWCreateFrameFromGWorldAndRectPartial( &newFrameP, tempPictGWorldP,
  441.                             tempMaskGWorldP, tempTempMaskGWorldP, &frameRect, maskType);
  442.         
  443.                     if (err == noErr)
  444.                     {
  445.                         err = SWAddFrame(tempSpriteP, newFrameP);
  446.                     }
  447.         
  448.                     if (err != noErr)
  449.                     {
  450.                         SWDisposeFrame(&newFrameP);
  451.                         SWDisposeSprite(&tempSpriteP);
  452.                         break;
  453.                     }
  454.                 }
  455.                 SWCreateFrameFromGWorldAndRectFinish( tempTempMaskGWorldP );
  456.             }
  457.             
  458.             if (err == noErr)
  459.             {
  460.                     // If a pixel mask is wanted, fix the tempMaskGWorld 
  461.                     // if the depth is 8-bits or less.
  462.                 if ((maskType & kPixelMask) != 0)
  463.                 {
  464.                     if (destSpriteWorldP->pixelDepth <= 8 && needToInvertMask)
  465.                     {
  466.                         SWInvertGWorld(tempMaskGWorldP);
  467.                     }
  468.                 }        // If no pixel Mask wanted, dispose of the
  469.                 else    // GWorld we used to make the region mask.
  470.                 {
  471.                     if (tempMaskGWorldP != NULL)
  472.                     {
  473.                         DisposeGWorld( tempMaskGWorldP );
  474.                         tempMaskGWorldP = NULL;
  475.                     }
  476.                 }
  477.                 
  478.                 SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  479.                 SWSetCurrentFrameIndex(tempSpriteP, 0);
  480.                 tempSpriteP->sharedPictGWorld = tempPictGWorldP;
  481.                 tempSpriteP->sharedMaskGWorld = tempMaskGWorldP;
  482.                 
  483.                 *newSpriteP = tempSpriteP;
  484.             }
  485.         }
  486.     }
  487.     
  488.     if ( rectArrayHndl != NULL )
  489.     {
  490.         HUnlock( rectArrayHndl );
  491.         ReleaseResource( rectArrayHndl );
  492.     }
  493.     
  494.     SWSetStickyIfError( err );
  495.     return err;
  496. }
  497.  
  498.  
  499. ///--------------------------------------------------------------------------------------
  500. //  SWCreateSpriteFromSinglePictXY
  501. //
  502. //  height/width code contributed by Mohsan Khan, 96-06-13. You can email Mohsan Khan at
  503. //    xybernic@algonet.se, or visit his web page at www.algonet.se/~xybernic.
  504. ///--------------------------------------------------------------------------------------
  505.  
  506. SW_FUNC OSErr SWCreateSpriteFromSinglePictXY(
  507.         SpriteWorldPtr destSpriteWorldP,
  508.         SpritePtr* newSpriteP,
  509.         void* spriteStorageP,
  510.         short pictResID,
  511.         short maskResID,
  512.         short frameWidth,
  513.         short frameHeight,
  514.         short borderWidth,
  515.         short borderHeight,
  516.         short maxFrames,
  517.         MaskType maskType)
  518. {
  519.     OSErr            err = noErr;
  520.     PicHandle        tempPic;
  521.     GWorldPtr        tempPictGWorldP, 
  522.                     tempMaskGWorldP, 
  523.                     tempTempMaskGWorldP;
  524.     Rect            frameRect;
  525.     SpritePtr        tempSpriteP;
  526.     FramePtr        newFrameP;
  527.     short            frame;
  528.     Boolean            needToInvertMask;
  529.  
  530.     SW_ASSERT(destSpriteWorldP != NULL);
  531.  
  532.     tempPictGWorldP = NULL;
  533.     tempMaskGWorldP = NULL;
  534.     *newSpriteP = NULL;
  535.     needToInvertMask = true;
  536.  
  537.  
  538.     tempPic = GetPicture( pictResID );
  539.     if ( tempPic == nil )
  540.     {
  541.         err = MemError();
  542.         if ( err == noErr )
  543.             err = resNotFound;
  544.     }
  545.     else
  546.     {
  547.         ReleaseResource( (Handle)tempPic );
  548.     }
  549.  
  550.     if ( err == noErr )
  551.     {    
  552.         {
  553.                 // Create the GWorld that contains the Sprite's image.
  554.             err = SWCreateGWorldFromPictResource( destSpriteWorldP, &tempPictGWorldP, pictResID );
  555.             
  556.                 // Create the GWorld used to hold the mask. 
  557.             if ( err == noErr && maskType != kNoMask )
  558.                 err = SWCreateGWorldFromPictResource(
  559.                     destSpriteWorldP, &tempMaskGWorldP, maskResID );
  560.             
  561.             if (err == noErr)
  562.             {
  563.                     // If this is a self-masking Sprite, create the mask based on the image.
  564.                 if ( pictResID == maskResID && tempMaskGWorldP != NULL )
  565.                 {
  566.                     err = SWCreatePixelMaskFromGWorld( tempPictGWorldP, tempMaskGWorldP, (RectPtr) NULL );
  567.                     needToInvertMask = false;
  568.                     
  569.                         // If the depth is 8-bits or less, and we need to create a region mask,
  570.                         // invert the maskGWorld so the region mask is created correctly.
  571.                     if (destSpriteWorldP->pixelDepth <= 8 && (maskType & kRegionMask) != 0 )
  572.                     {
  573.                         SWInvertGWorld(tempMaskGWorldP);
  574.                         needToInvertMask = true;
  575.                     }
  576.                 }
  577.                 else if ( (maskType & kPixelMask) != 0 )
  578.                 {
  579.                         // For Sprites that are not self-masking and have a pixel mask, we
  580.                         // should still fix the GWorld's image, in case SWTransparentColor
  581.                         // is not white, or in case the depth is 16-bits or above.
  582.                     SWFixImageGWorld( tempPictGWorldP, tempMaskGWorldP, (RectPtr) NULL );
  583.                 }
  584.             }
  585.             
  586.             if ( maxFrames == 0 )
  587.             {
  588.                 maxFrames = (tempPictGWorldP->portRect.right/frameWidth) *
  589.                             (tempPictGWorldP->portRect.bottom/frameHeight);
  590.             }
  591.             
  592.             if (err == noErr)
  593.             {
  594.                 err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  595.             }
  596.             
  597.             if (err == noErr)
  598.             {
  599.                 err = SWCreateFrameFromGWorldAndRectStart( &tempTempMaskGWorldP, frameWidth, 
  600.                         frameHeight, maskType );
  601.             }
  602.             
  603.             if (err == noErr)
  604.             {
  605.                 frameRect.left = 0;
  606.                 frameRect.top = 0;
  607.                 frameRect.right = frameWidth;
  608.                 frameRect.bottom = frameHeight;
  609.                 
  610.                 for (frame = 0; frame < maxFrames; frame++)
  611.                 {
  612.                     err = SWCreateFrameFromGWorldAndRectPartial( &newFrameP, tempPictGWorldP,
  613.                             tempMaskGWorldP, tempTempMaskGWorldP, &frameRect, maskType);
  614.  
  615.                     if (err == noErr)
  616.                     {
  617.                         err = SWAddFrame(tempSpriteP, newFrameP);
  618.                         if ( frame < maxFrames-1 )
  619.                         {
  620.                             frameRect.left += frameWidth + borderWidth;
  621.                             frameRect.right = frameRect.left + frameWidth;
  622.                             if ( frameRect.right > tempPictGWorldP->portRect.right )
  623.                             {
  624.                                 frameRect.left = 0;
  625.                                 frameRect.right = frameWidth;
  626.                                 frameRect.top += frameHeight + borderHeight;
  627.                                 frameRect.bottom = frameRect.top + frameHeight;
  628.                                 
  629.                                 if ( frameRect.bottom > tempPictGWorldP->portRect.bottom )
  630.                                 {
  631.                                     err = kOutOfRangeErr;
  632.                                 }
  633.                             }
  634.                         }
  635.                     }
  636.                     if ( err != noErr )
  637.                     {
  638.                         SWDisposeFrame(&newFrameP);
  639.                         SWDisposeSprite(&tempSpriteP);
  640.                         break;
  641.                     }
  642.                 } // end for
  643.                 SWCreateFrameFromGWorldAndRectFinish( tempTempMaskGWorldP );
  644.             }
  645.  
  646.             if (err == noErr)
  647.             {
  648.                     // If a pixel mask is wanted, fix the tempMaskGWorld 
  649.                     // if the depth is 8-bits or less.
  650.                 if ((maskType & kPixelMask) != 0)
  651.                 {
  652.                     if (destSpriteWorldP->pixelDepth <= 8 && needToInvertMask)
  653.                     {
  654.                         SWInvertGWorld(tempMaskGWorldP);
  655.                     }
  656.                 }        // If no pixel Mask wanted, dispose
  657.                 else    // of the GWorld we used to make region
  658.                 {
  659.                     if (tempMaskGWorldP != NULL)
  660.                     {
  661.                         DisposeGWorld( tempMaskGWorldP );
  662.                         tempMaskGWorldP = NULL;
  663.                     }
  664.                 }
  665.                 
  666.                 SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  667.                 SWSetCurrentFrameIndex(tempSpriteP, 0);
  668.                 tempSpriteP->sharedPictGWorld = tempPictGWorldP;
  669.                 tempSpriteP->sharedMaskGWorld = tempMaskGWorldP;
  670.  
  671.                 *newSpriteP = tempSpriteP;
  672.             }
  673.         }
  674.     }
  675.     SWSetStickyIfError( err );
  676.     return err;
  677. }
  678.  
  679.  
  680. ///--------------------------------------------------------------------------------------
  681. //    SWCreateSpriteFromRLEResource
  682. ///--------------------------------------------------------------------------------------
  683.  
  684. SW_FUNC OSErr SWCreateSpriteFromRLEResource(
  685.     SpritePtr *srcSpriteP,
  686.     void* spriteStorageP,
  687.     short rleResID,
  688.     short mask)
  689. {
  690.     SpritePtr            tempSpriteP;
  691.     FramePtr            tempFrameP;
  692.     RLEPixelDataHdl        spriteData;
  693.     short                numFrames;
  694.     short                frame;
  695.     OSErr                 err = noErr;
  696.     GDHandle            device;
  697.     short                depth;
  698.     Rect                frameRect;
  699.     char                state;
  700.     PixMapHandle        pixMapH;
  701.     GWorldPtr            saveGWorld;
  702.     GDHandle            saveGDevice;
  703.     Boolean                createGWorld;
  704.     
  705.     *srcSpriteP = NULL;
  706.     
  707.     device = GetGDevice();
  708.         
  709.     spriteData = (RLEPixelDataHdl) GetResource( kRLEResourceType, rleResID );
  710.     if ( spriteData != NULL )
  711.     {
  712.  
  713.             // read header data
  714.         if ( err == noErr )
  715.         {
  716.             numFrames = (**spriteData).frames;
  717.             depth = (**spriteData).depth;
  718.             SetRect( &frameRect,
  719.                 0,0,
  720.                 (**spriteData).width,
  721.                 (**spriteData).height );
  722.         }
  723.         
  724.         err = SWCreateSprite(&tempSpriteP,spriteStorageP,numFrames);
  725.         if ( err == noErr )
  726.         {
  727.             createGWorld = (mask & ( kSolidMask | kPixelMask | kRegionMask )) != 0;
  728.         
  729.             for (frame = 0; err == noErr && frame < tempSpriteP->maxFrames; frame++)
  730.             {
  731.                 err = SWCreateFrame(device,&tempFrameP,&frameRect,depth, createGWorld);
  732.                 if ( err == noErr )
  733.                 {
  734.                     tempFrameP->rleDataH = (RLETokenHandle) spriteData;
  735.                     tempFrameP->rleTokenStart = NULL;
  736.             
  737.                     err = SWAddFrame( tempSpriteP,tempFrameP);
  738.                 }
  739.             }
  740.             
  741.             if ( err == noErr )
  742.             {
  743.                 SWSetSpriteFrameRange(tempSpriteP, 0, numFrames - 1);
  744.                 SWSetCurrentFrameIndex(tempSpriteP, 0);
  745.     
  746.                 *srcSpriteP = tempSpriteP;
  747.             }
  748.             else
  749.             {
  750.                 SWDisposeSprite( &tempSpriteP );
  751.             }
  752.         }
  753.         
  754.         if ( err == noErr )
  755.         {
  756.             SWLockSprite( tempSpriteP );
  757.             
  758.             GetGWorld( &saveGWorld, &saveGDevice );
  759.  
  760.             for (frame = 0; err == noErr && frame < tempSpriteP->numFrames; frame++)
  761.             {
  762.                 tempFrameP = tempSpriteP->frameArray[frame];
  763.                 
  764.                 if ( createGWorld )
  765.                 {
  766.                     SetGWorld( tempFrameP->framePort, (GDHandle) NULL );
  767.                         
  768.                         // draw the image
  769.                     BlitPixieClearDrawProc(
  770.                         tempFrameP, tempFrameP, &tempFrameP->frameRect, &tempFrameP->frameRect );
  771.                     BlitPixieRLEDrawProc(
  772.                         tempFrameP, tempFrameP, &tempFrameP->frameRect, &tempFrameP->frameRect );
  773.                 }
  774.                 
  775.                 if ( (mask & kPixelMask) || (mask & kRegionMask) )
  776.                 {
  777.                     err = NewGWorld( &tempFrameP->maskPort, depth, &tempFrameP->frameRect, 
  778.                             (CTabHandle) NULL, tempFrameP->frameDevice, (GWorldFlags) 0 );
  779.                 
  780.                         // draw the pixel mask
  781.                     if ( err == noErr )
  782.                     {
  783.                         pixMapH = GetGWorldPixMap( tempFrameP->maskPort );
  784.                         (void)LockPixels( pixMapH );
  785.                         HLockHi( (Handle)pixMapH );
  786.                         tempFrameP->maskPixHndl = pixMapH;
  787.                         tempFrameP->maskDevice = GetGWorldDevice( tempFrameP->maskPort );
  788.                         tempFrameP->maskPix = (PixMapPtr)StripAddress( *pixMapH );
  789.                         tempFrameP->maskBaseAddr = GetPixBaseAddr( pixMapH );
  790.                     
  791.                         SetGWorld( tempFrameP->maskPort, (GDHandle) NULL );
  792.                         ForeColor(blackColor);
  793.                         BackColor(whiteColor);
  794.                         
  795.                         if ( depth <= 8 )
  796.                             PaintRect( &tempFrameP->frameRect );
  797.                         else
  798.                             EraseRect( &tempFrameP->frameRect );
  799.                         
  800.                         BlitPixieRLEColor(
  801.                             (UInt8*) tempFrameP->rleTokenStart,
  802.                             0L,
  803.                             (UInt8*) tempFrameP->maskBaseAddr,
  804.                             tempFrameP->frameRowBytes );
  805.                     }
  806.                 }
  807.                 
  808.                     // create a region mask
  809.                 if ( err == noErr && (mask & kRegionMask) )
  810.                 {
  811.                     if ( depth <= 8 )
  812.                         InvertRect( &tempFrameP->frameRect );
  813.                 
  814.                     err = SWCreateRegionFromGWorldAndRect(
  815.                         &tempFrameP->maskRgn,
  816.                         tempFrameP->maskPort,
  817.                         &tempFrameP->frameRect );
  818.                     
  819.                     if ( depth <= 8 )
  820.                         InvertRect( &tempFrameP->frameRect );
  821.                 
  822.                 }
  823.         
  824.                     // dispose of pixel mask, if not needed
  825.                 if ( err == noErr && !(mask & kPixelMask) )
  826.                 {
  827.                     DisposeGWorld( tempFrameP->maskPort );
  828.                     tempFrameP->maskPort = NULL;
  829.                 }
  830.             
  831.             }
  832.             
  833.             SetGWorld( saveGWorld, saveGDevice );
  834.             
  835.             SWUnlockSprite( tempSpriteP );
  836.         }    
  837.         
  838.         if ( err == noErr )
  839.         {
  840.             // detach, if it is a resource handle
  841.             state = HGetState( (Handle) spriteData );
  842.             if ( state & 0x20 )
  843.             {
  844.                 DetachResource( (Handle) spriteData );
  845.                 err = ResError();
  846.             }
  847.         }
  848.     }
  849.     else
  850.     {
  851.         err = ResError();
  852.         if ( err == noErr )
  853.             err = resNotFound;
  854.     }
  855.  
  856.     SWSetStickyIfError( err );
  857.     return err;
  858. }
  859.  
  860.  
  861. ///--------------------------------------------------------------------------------------
  862. //    SWUpdateSpriteFromPictResource
  863. ///--------------------------------------------------------------------------------------
  864.  
  865. SW_FUNC OSErr SWUpdateSpriteFromPictResource(
  866.     SpritePtr theSpriteP,
  867.     short pictResID)
  868. {
  869.     OSErr             err = noErr;
  870.     GDHandle        currentGDH;
  871.     GWorldPtr        currentGWorld;
  872.     GWorldPtr        frameGWorld;
  873.     PicHandle        pictH;
  874.     Rect            frameRect;
  875.     short            frame;
  876.     
  877.     SW_ASSERT(theSpriteP != NULL);
  878.     
  879.     GetGWorld( ¤tGWorld, ¤tGDH );
  880.     
  881.     SWLockSprite( theSpriteP );
  882.     
  883.         // For single-pict Sprites...
  884.     if ( theSpriteP->sharedPictGWorld != NULL )
  885.     {
  886.         SetGWorld( theSpriteP->sharedPictGWorld, NULL );
  887.         pictH = GetPicture( pictResID );
  888.         if ( pictH != NULL )
  889.         {
  890.             frameRect = theSpriteP->sharedPictGWorld->portRect;
  891.             EraseRect( &frameRect );
  892.             DrawPicture( pictH, &frameRect );
  893.             ReleaseResource( (Handle)pictH );
  894.             
  895.                 // Fix the GWorld's image, so it will blit properly in depths
  896.                 // above 8 bits, and so any pixels matching SWTransparentColor will
  897.                 // be converted to the correct transparent pixel value.
  898.             SWFastWhitenGWorld( theSpriteP->sharedPictGWorld );
  899.         }
  900.         else
  901.         {
  902.             err = MemError();
  903.             if ( err == noErr )
  904.                 err = resNotFound;
  905.         }
  906.     }
  907.     else
  908.     {        // For Sprites where each frame was loaded from a separate pict...
  909.         for (frame = 0; frame < theSpriteP->maxFrames; frame++)
  910.         {
  911.             frameGWorld = theSpriteP->frameArray[frame]->framePort;
  912.             
  913.             if ( frameGWorld != NULL )
  914.             {
  915.                 SetGWorld( frameGWorld, nil );
  916.                 pictH = GetPicture( pictResID + frame );
  917.                 if ( pictH != NULL )
  918.                 {
  919.                     frameRect = frameGWorld->portRect;
  920.                     EraseRect( &frameRect );
  921.                     DrawPicture( pictH, &frameRect );
  922.                     ReleaseResource( (Handle)pictH );
  923.                     
  924.                         // Fix the GWorld's image, so it will blit properly in depths
  925.                         // above 8 bits, and so any pixels matching SWTransparentColor will
  926.                         // be converted to the correct transparent pixel value.
  927.                     SWFastWhitenGWorld( frameGWorld );
  928.                 }
  929.                 else
  930.                 {
  931.                     err = MemError();
  932.                     if ( err == noErr )
  933.                         err = resNotFound;
  934.                     break;
  935.                 }
  936.             }
  937.         }
  938.     }
  939.     SetGWorld( currentGWorld, currentGDH );
  940.     
  941.     SWSetStickyIfError( err );
  942.     return err;
  943. }
  944.  
  945.  
  946. ///--------------------------------------------------------------------------------------
  947. //    CalcMaxWidthHeight - called by SWCreateSpriteFromSinglePict
  948. ///--------------------------------------------------------------------------------------
  949.  
  950. void CalcMaxWidthHeight( 
  951.     RectArrayPtr newRectArrayP, 
  952.     short *maxWidthP, 
  953.     short *maxHeightP )
  954. {
  955.     short         frame;
  956.     Rect         *rectP;
  957.     short         maxWidth, maxHeight;
  958.     
  959.     
  960.     maxWidth = 0;
  961.     maxHeight = 0;
  962.     
  963.     rectP = &newRectArrayP->frameRects[0];
  964.     for( frame = 0; frame < newRectArrayP->numFrames; frame++ ) 
  965.     {
  966.         if ( rectP->right - rectP->left > maxWidth ) 
  967.         {
  968.             maxWidth = rectP->right - rectP->left;
  969.         }
  970.         if ( rectP->bottom - rectP->top > maxHeight ) 
  971.         {
  972.             maxHeight = rectP->bottom - rectP->top;
  973.         }
  974.         rectP++;
  975.     }
  976.     *maxWidthP = maxWidth;
  977.     *maxHeightP =maxHeight;
  978. }
  979.  
  980.  
  981. ///--------------------------------------------------------------------------------------
  982. //    SWSaveRLESprite
  983. ///--------------------------------------------------------------------------------------
  984.  
  985. SW_FUNC OSErr SWSaveRLESprite(
  986.     SpritePtr srcSpriteP,
  987.     short rleResID)
  988. {
  989.     OSErr                 err = noErr;
  990.     RLEPixelDataHdl        spriteData;
  991.     Handle                oldresHandle;
  992.     
  993.     spriteData = (RLEPixelDataHdl) srcSpriteP->frameArray[0]->rleDataH;
  994.     if ( spriteData == NULL )
  995.         err = kSpriteNotCompiledErr;
  996.     
  997.     if ( err == noErr )
  998.     {
  999.         // get rid of old resource, if any
  1000.         SetResLoad(false);
  1001.         oldresHandle = GetResource(kRLEResourceType, rleResID);
  1002.         SetResLoad(true);
  1003.         if ( oldresHandle != NULL)
  1004.         {
  1005.             RemoveResource( oldresHandle);
  1006.             err = ResError();
  1007.         }
  1008.     }
  1009.         
  1010.     if ( err == noErr )
  1011.     {
  1012.         if ( err == noErr )
  1013.         {
  1014.                 // attach the new one
  1015.             AddResource((Handle) spriteData, kRLEResourceType, rleResID, "\p");
  1016.             err = ResError();
  1017.         }
  1018.         
  1019.         if ( err == noErr )
  1020.         {
  1021.                 // write it to disk
  1022.             WriteResource((Handle) spriteData);
  1023.             err = ResError();
  1024.         }
  1025.         
  1026.         if (err == noErr )
  1027.         {
  1028.             DetachResource( (Handle) spriteData );
  1029.             err = ResError();
  1030.         }
  1031.     
  1032.     }
  1033.     
  1034.     SWSetStickyIfError( err );
  1035.     return err;
  1036. }
  1037.  
  1038.  
  1039. ///--------------------------------------------------------------------------------------
  1040. //    SWCloneSprite
  1041. ///--------------------------------------------------------------------------------------
  1042.  
  1043. SW_FUNC OSErr SWCloneSprite(
  1044.     SpritePtr    cloneSpriteP,
  1045.     SpritePtr*    newSpriteP,
  1046.     void*        spriteStorageP)
  1047. {
  1048.     SpritePtr         tempSpriteP;
  1049.     short             index;
  1050.     Size            frameArraySize;
  1051.     OSErr             err = noErr;
  1052.     
  1053.     SW_ASSERT(cloneSpriteP != NULL);
  1054.     
  1055.         // Allocate memory for the new Sprite
  1056.     tempSpriteP = (spriteStorageP == NULL) ? (SpritePtr)NewPtr(sizeof(SpriteRec)) : (SpritePtr)spriteStorageP;
  1057.     if (tempSpriteP == NULL)
  1058.         err = MemError();
  1059.     
  1060.     if (err == noErr)
  1061.     {
  1062.             // Make sure the Ptr passed to this function is large enough.
  1063.         SW_ASSERT( GetPtrSize((Ptr)tempSpriteP) >= sizeof(SpriteRec) );
  1064.         
  1065.             // copy the clone sprite into the temp sprite
  1066.         *tempSpriteP = *cloneSpriteP;
  1067.  
  1068.             // clear the layer fields, in case the parent sprite is in a layer
  1069.         tempSpriteP->parentSpriteLayerP = NULL;
  1070.         tempSpriteP->nextSpriteP = NULL;
  1071.         tempSpriteP->prevSpriteP = NULL;
  1072.         
  1073.             // Initialize other fields
  1074.         tempSpriteP->spriteMoveProc = SWTempSpriteMoveProc;
  1075.         tempSpriteP->realSpriteMoveProc = cloneSpriteP->realSpriteMoveProc;
  1076.     }
  1077.     
  1078.     if (err == noErr)
  1079.     {
  1080.             // Create a new frameArray for this sprite
  1081.         frameArraySize = (Size)cloneSpriteP->maxFrames * sizeof(FramePtr);
  1082.         tempSpriteP->frameArray = (FramePtr *)NewPtrClear(frameArraySize);
  1083.  
  1084.         if (tempSpriteP->frameArray != NULL)
  1085.         {
  1086.                 // copy the frame array, and increment useCount for each frame
  1087.             for (index = 0; index < cloneSpriteP->maxFrames; index++)
  1088.             {
  1089.                 tempSpriteP->frameArray[index] = cloneSpriteP->frameArray[index];
  1090.                 SW_ASSERT(tempSpriteP->frameArray[index] != NULL );
  1091.                 tempSpriteP->frameArray[index]->useCount++;
  1092.             }
  1093.             
  1094.         }
  1095.         else
  1096.         {
  1097.             err = MemError();
  1098.             DisposePtr((Ptr)tempSpriteP);
  1099.         }
  1100.     }
  1101.     
  1102.     if (err == noErr)
  1103.         *newSpriteP = tempSpriteP;
  1104.  
  1105.     SWSetStickyIfError( err );
  1106.     return err;
  1107. }
  1108.  
  1109.  
  1110. ///--------------------------------------------------------------------------------------
  1111. //    SWCloneSpriteFromTile
  1112. ///--------------------------------------------------------------------------------------
  1113.  
  1114. SW_FUNC OSErr SWCloneSpriteFromTile(
  1115.     SpriteWorldPtr spriteWorldP,
  1116.     SpritePtr* newSpriteP,
  1117.     void* spriteStorageP,
  1118.     short firstTileID,
  1119.     short lastTileID)
  1120. {
  1121.     OSErr             err;
  1122.     SpritePtr         tempSpriteP;
  1123.     FramePtr         tileFrameP;
  1124.     short             curTileID, curIndex, numFrames;
  1125.     
  1126.     SW_ASSERT(firstTileID <= lastTileID);
  1127.     SW_ASSERT(spriteWorldP->tileFrameArray != NULL);
  1128.     SW_ASSERT(firstTileID >= 0 && lastTileID < spriteWorldP->maxNumTiles);
  1129.     
  1130.     *newSpriteP = NULL;
  1131.     numFrames = (lastTileID - firstTileID) + 1;
  1132.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, numFrames);
  1133.     
  1134.     if (err == noErr)
  1135.     {
  1136.         for (curTileID = firstTileID; curTileID <= lastTileID; curTileID++)
  1137.         {
  1138.             tileFrameP = spriteWorldP->tileFrameArray[curTileID];
  1139.             SW_ASSERT(tileFrameP != NULL);
  1140.             err = SWAddFrame(tempSpriteP, tileFrameP);
  1141.  
  1142.             if (err != noErr)
  1143.             {
  1144.                 SWDisposeSprite(&tempSpriteP);
  1145.                 break;
  1146.             }
  1147.         }
  1148.  
  1149.         if (err == noErr)
  1150.         {
  1151.             SWSetSpriteFrameRange(tempSpriteP, 0, numFrames - 1);
  1152.             
  1153.                 // Set current index to be the same as the Tile's current image, if possible.
  1154.             curIndex = spriteWorldP->curTileImage[firstTileID];
  1155.             if (curIndex >= firstTileID && curIndex <= lastTileID)
  1156.                 curIndex = spriteWorldP->curTileImage[firstTileID] - firstTileID;
  1157.             else
  1158.                 curIndex = 0;
  1159.             
  1160.             SWSetCurrentFrameIndex(tempSpriteP, curIndex);
  1161.             *newSpriteP = tempSpriteP;
  1162.         }
  1163.     }
  1164.  
  1165.     SWSetStickyIfError( err );
  1166.     return err;
  1167. }
  1168.  
  1169. #pragma mark -
  1170.  
  1171. ///--------------------------------------------------------------------------------------
  1172. //    SWRemoveSpriteFromAnimation
  1173. ///--------------------------------------------------------------------------------------
  1174.  
  1175. SW_FUNC void  SWRemoveSpriteFromAnimation(
  1176.     SpriteWorldPtr    spriteWorldP,
  1177.     SpritePtr        spriteP,
  1178.     Boolean            disposeOfSprite)
  1179. {
  1180.     SW_ASSERT(spriteWorldP != NULL && spriteP != NULL);
  1181.     
  1182.     SWSetSpriteVisible( spriteP, false );
  1183.     SWRemoveSprite(spriteP);
  1184.     SWAddSprite(spriteWorldP->deadSpriteLayerP, spriteP);
  1185.     
  1186.     if ( disposeOfSprite )
  1187.     {
  1188.         spriteP->spriteRemoval = kSWRemoveAndDisposeSprite;
  1189.     }
  1190.     else
  1191.     {
  1192.         spriteP->spriteRemoval = kSWRemoveSprite;
  1193.     }
  1194. }
  1195.     
  1196.  
  1197. ///--------------------------------------------------------------------------------------
  1198. //    SWDisposeSprite
  1199. ///--------------------------------------------------------------------------------------
  1200.  
  1201. SW_FUNC void SWDisposeSprite(
  1202.     SpritePtr *deadSpritePP)
  1203. {
  1204.     SpritePtr    deadSpriteP = *deadSpritePP;
  1205.     
  1206.     if (deadSpriteP != NULL)
  1207.     {
  1208.         SWCloseSprite(deadSpriteP);
  1209.         DisposePtr((Ptr)deadSpriteP);
  1210.         
  1211.         *deadSpritePP = NULL;    // Set the original pointer to NULL
  1212.     }
  1213. }
  1214.  
  1215.  
  1216. ///--------------------------------------------------------------------------------------
  1217. //    SWCloseSprite
  1218. ///--------------------------------------------------------------------------------------
  1219.  
  1220. SW_FUNC void SWCloseSprite(
  1221.     SpritePtr deadSpriteP)
  1222. {
  1223.     short             frame;
  1224.     Boolean            framesDisposed;
  1225.     
  1226.     if (deadSpriteP != NULL)
  1227.     {
  1228.         for (frame = 0; frame < deadSpriteP->numFrames; frame++)
  1229.         {
  1230.             framesDisposed = SWDisposeFrame(&deadSpriteP->frameArray[frame]);
  1231.         }
  1232.         
  1233.         if ( framesDisposed )
  1234.         {
  1235.             if ( deadSpriteP->sharedPictGWorld != NULL )
  1236.             {
  1237.                 DisposeGWorld(deadSpriteP->sharedPictGWorld );
  1238.                 deadSpriteP->sharedPictGWorld = NULL;
  1239.             }
  1240.         
  1241.             if ( deadSpriteP->sharedMaskGWorld != NULL )
  1242.             {
  1243.                 DisposeGWorld(deadSpriteP->sharedMaskGWorld );
  1244.                 deadSpriteP->sharedMaskGWorld = NULL;
  1245.             }
  1246.         }
  1247.         
  1248.         DisposePtr((Ptr)deadSpriteP->frameArray);
  1249.         deadSpriteP->frameArray = NULL;
  1250.     }
  1251. }
  1252.  
  1253.  
  1254. ///--------------------------------------------------------------------------------------
  1255. //    SWLockSprite
  1256. ///--------------------------------------------------------------------------------------
  1257.  
  1258. SW_FUNC void SWLockSprite(
  1259.     SpritePtr srcSpriteP)
  1260. {
  1261.     register long         curFrame;
  1262.     FramePtr            srcFrameP;
  1263.     RLEPixelDataHdl        spriteData;
  1264.     long                dataLength;
  1265.     TokenDataType        *tokens;
  1266.     long                offset;
  1267.     
  1268.     SW_ASSERT(srcSpriteP != NULL);
  1269.  
  1270.     for (curFrame = 0; curFrame < srcSpriteP->numFrames; curFrame++)
  1271.     {
  1272.         SWLockFrame(srcSpriteP->frameArray[curFrame]);
  1273.     }
  1274.  
  1275.         // Lock RLE Sprite tokens, and check their validity if assertions are on
  1276.     spriteData = (RLEPixelDataHdl) srcSpriteP->frameArray[0]->rleDataH;
  1277.     if ( spriteData != NULL )
  1278.     {
  1279.         HLock( (Handle) spriteData );
  1280.         
  1281.         dataLength = GetHandleSize( (Handle) spriteData ) - kRLEResourceHeaderSize;
  1282.         SW_ASSERT(dataLength > 0 );
  1283.         
  1284.         offset = 0;
  1285.         tokens = (TokenDataType *) ((char *) *spriteData + kRLEResourceHeaderSize);
  1286.         
  1287.         for (curFrame = 0; curFrame < srcSpriteP->numFrames; curFrame++)
  1288.         {
  1289.             srcFrameP = srcSpriteP->frameArray[curFrame];
  1290.             SW_ASSERT( srcFrameP->rleDataH == (RLETokenHandle) spriteData );
  1291.         
  1292.             srcFrameP->rleTokenStart = (RLETokenPtr) tokens;
  1293.         
  1294.                 // skip to start of next frame
  1295.             while ( *tokens != (kEndShapeToken << kTokenShift) )
  1296.             {
  1297.                     // check for valid data
  1298.                 SW_ASSERT( (*tokens >> kTokenShift) == kLineStartToken );
  1299.                 
  1300.                     // skip to next row
  1301.                 offset += (*tokens & kCountMask) + sizeof(TokenDataType);
  1302.                 tokens = (TokenDataType *) ((char *) tokens + sizeof(TokenDataType) + (*tokens & kCountMask));
  1303.             
  1304.                     // check for invalid input data (overflow)
  1305.                 SW_ASSERT( offset <= dataLength );
  1306.             }
  1307.                 // skip end token
  1308.             offset += sizeof(TokenDataType);
  1309.             tokens = (TokenDataType *) ((char *) tokens + sizeof(TokenDataType) );
  1310.         }
  1311.     }
  1312. }
  1313.  
  1314.  
  1315. ///--------------------------------------------------------------------------------------
  1316. //    SWUnlockSprite
  1317. ///--------------------------------------------------------------------------------------
  1318.  
  1319. SW_FUNC void SWUnlockSprite(
  1320.     SpritePtr srcSpriteP)
  1321. {
  1322.     register long         curFrame;
  1323.     RLEPixelDataHdl        spriteData;
  1324.     FramePtr            srcFrameP;
  1325.     
  1326.     SW_ASSERT(srcSpriteP != NULL);
  1327.  
  1328.     for (curFrame = 0; curFrame < srcSpriteP->numFrames; curFrame++)
  1329.     {
  1330.         SWUnlockFrame(srcSpriteP->frameArray[curFrame]);
  1331.     }
  1332.  
  1333.     spriteData = (RLEPixelDataHdl) srcSpriteP->frameArray[0]->rleDataH;
  1334.     if ( spriteData != NULL )
  1335.     {
  1336.         for (curFrame = 0; curFrame < srcSpriteP->numFrames; curFrame++)
  1337.         {
  1338.             srcFrameP = srcSpriteP->frameArray[curFrame];
  1339.         
  1340.             srcFrameP->rleTokenStart = NULL;
  1341.         }
  1342.         
  1343.         HUnlock( (Handle) spriteData );
  1344.     }
  1345. }
  1346.  
  1347.  
  1348. ///--------------------------------------------------------------------------------------
  1349. //    SWFlipSprite - works in any depth, but is slow in depths below 8-bits.
  1350. ///--------------------------------------------------------------------------------------
  1351.  
  1352. SW_FUNC void SWFlipSprite(
  1353.     SpritePtr srcSpriteP,
  1354.     FlipType direction )
  1355. {
  1356.     long             curFrame;
  1357.     FramePtr        srcFrameP;
  1358.     
  1359.     for (curFrame = 0; curFrame < srcSpriteP->numFrames; curFrame++)
  1360.     {
  1361.         srcFrameP = srcSpriteP->frameArray[curFrame];
  1362.         
  1363.             // flip image
  1364.         if ( srcFrameP->framePort != NULL )
  1365.         {
  1366.             if ( direction & kSWFlipHorizontal )
  1367.                 SWFlipPixelsHorizontally( srcFrameP->framePort, &srcFrameP->frameRect );
  1368.         
  1369.             if ( direction & kSWFlipVertical )
  1370.                 SWFlipPixelsVertically( srcFrameP->framePort, &srcFrameP->frameRect );
  1371.             
  1372.         
  1373.                 // Now update this frame's mask
  1374.             if (srcFrameP->maskRgn == NULL
  1375. //                && srcFrameP->rleDataH == NULL
  1376. #if SW_68K        
  1377.                 && srcFrameP->pixCodeH == NULL
  1378. #endif
  1379.                 )
  1380.             {
  1381.                     // If the only kind of mask is a pixel mask, we can update it 
  1382.                     // quickly by flipping it in the same way that we flipped the image.
  1383.                 if ( srcFrameP->maskPort != NULL )
  1384.                 {
  1385.                     if ( direction & kSWFlipHorizontal )
  1386.                         SWFlipPixelsHorizontally( srcFrameP->maskPort, &srcFrameP->frameRect );
  1387.                 
  1388.                     if ( direction & kSWFlipVertical )
  1389.                         SWFlipPixelsVertically( srcFrameP->maskPort, &srcFrameP->frameRect );
  1390.                 }
  1391.             }
  1392.             else
  1393.             {
  1394.                     // For all other kinds of masks and mask combinations, it's fastest
  1395.                     // to use SWUpdateFrameMasks.
  1396.                 SWUpdateFrameMasks( srcFrameP );
  1397.             }
  1398.         }
  1399.     }
  1400. }
  1401.  
  1402.  
  1403. ///--------------------------------------------------------------------------------------
  1404. //    SWAddFrame
  1405. ///--------------------------------------------------------------------------------------
  1406.  
  1407. SW_FUNC OSErr SWAddFrame(
  1408.     SpritePtr srcSpriteP,
  1409.     FramePtr newFrameP)
  1410. {
  1411.     OSErr err = noErr;
  1412.     
  1413.     SW_ASSERT(srcSpriteP != NULL && newFrameP != NULL);
  1414.     
  1415.         // don’t exceed maximum number of frames
  1416.     if (srcSpriteP->numFrames < srcSpriteP->maxFrames)
  1417.     {
  1418.         srcSpriteP->frameArray[srcSpriteP->numFrames] = newFrameP;
  1419.  
  1420.             // increment the number of frames
  1421.         srcSpriteP->numFrames++;
  1422.         newFrameP->useCount++;
  1423.     }
  1424.     else
  1425.     {
  1426.         err = kMaxFramesErr;
  1427.     }
  1428.  
  1429.     SWSetStickyIfError( err );
  1430.     return err;
  1431. }
  1432.  
  1433.  
  1434. ///--------------------------------------------------------------------------------------
  1435. //    SWInsertFrame
  1436. ///--------------------------------------------------------------------------------------
  1437.  
  1438. SW_FUNC OSErr SWInsertFrame(
  1439.     SpritePtr    srcSpriteP,
  1440.     FramePtr    newFrameP,
  1441.     long        frameIndex)
  1442. {
  1443.     register long        index;
  1444.     register FramePtr    *frameArray;
  1445.     OSErr                err = noErr;
  1446.     
  1447.     SW_ASSERT(srcSpriteP != NULL && newFrameP != NULL);
  1448.     
  1449.     frameArray = srcSpriteP->frameArray;
  1450.  
  1451.         // don’t exceed maximum number of frames
  1452.     if (frameIndex < srcSpriteP->maxFrames && frameIndex >= 0 &&
  1453.         srcSpriteP->numFrames < srcSpriteP->maxFrames)
  1454.     {
  1455.             // move frames above frameIndex up
  1456.         for (index = srcSpriteP->numFrames; index > frameIndex; index--)
  1457.             frameArray[index] = frameArray[index - 1];
  1458.         
  1459.             // fill the hole
  1460.         frameArray[frameIndex] = newFrameP;
  1461.  
  1462.         srcSpriteP->numFrames++;
  1463.         newFrameP->useCount++;
  1464.     }
  1465.     else
  1466.     {
  1467.         err = kMaxFramesErr;
  1468.     }
  1469.  
  1470.     SWSetStickyIfError( err );
  1471.     return err;
  1472. }
  1473.  
  1474.  
  1475. ///--------------------------------------------------------------------------------------
  1476. //    SWRemoveFrame
  1477. ///--------------------------------------------------------------------------------------
  1478.  
  1479. SW_FUNC void SWRemoveFrame(
  1480.     SpritePtr srcSpriteP,
  1481.     FramePtr oldFrameP)
  1482. {
  1483.     register long curFrame;
  1484.     register FramePtr *frameArray;
  1485.     
  1486.     SW_ASSERT(srcSpriteP != NULL && oldFrameP != NULL);
  1487.  
  1488.     curFrame = srcSpriteP->numFrames;
  1489.     frameArray = srcSpriteP->frameArray;
  1490.  
  1491.         // find the frame to be removed
  1492.     while (curFrame--)
  1493.     {
  1494.         if (frameArray[curFrame] == oldFrameP)
  1495.         {
  1496.             srcSpriteP->numFrames--;
  1497.             oldFrameP->useCount--;
  1498.             
  1499.                 // move the rest of the frames down
  1500.             while (curFrame <= (srcSpriteP->numFrames - 1L))
  1501.             {
  1502.                 frameArray[curFrame] = frameArray[curFrame + 1L];
  1503.                 curFrame++;
  1504.             }
  1505.  
  1506.             break;
  1507.         }
  1508.     }
  1509. }
  1510.  
  1511.  
  1512. ///--------------------------------------------------------------------------------------
  1513. //    SWStdSpriteDrawProc - for drawing sprites
  1514. ///--------------------------------------------------------------------------------------
  1515.  
  1516. SW_FUNC void SWStdSpriteDrawProc(
  1517.     FramePtr srcFrameP,
  1518.     FramePtr dstFrameP,
  1519.     Rect* srcRect,
  1520.     Rect* dstRect)
  1521. {
  1522.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  1523.     
  1524.     if (srcFrameP->maskRgn != NULL)
  1525.     {
  1526.         Rect rgnRect = (**srcFrameP->maskRgn).rgnBBox;
  1527.  
  1528.             // move the mask region to the new sprite location
  1529.         OffsetRgn(srcFrameP->maskRgn,
  1530.             (dstRect->left - (srcRect->left - srcFrameP->frameRect.left) - rgnRect.left) 
  1531.             + srcFrameP->offsetPoint.h,
  1532.             (dstRect->top - (srcRect->top - srcFrameP->frameRect.top) - rgnRect.top)
  1533.             + srcFrameP->offsetPoint.v);
  1534.     }
  1535.     
  1536.         // CopyBits with a mask region is generally faster than CopyMask
  1537.     CopyBits((BitMapPtr)srcFrameP->framePix, (BitMapPtr)dstFrameP->framePix,
  1538.                 srcRect, dstRect, srcCopy, srcFrameP->maskRgn);
  1539. }
  1540.  
  1541. ///--------------------------------------------------------------------------------------
  1542. //    SWStdSpriteColorDrawProc - for drawing sprite masks
  1543. ///--------------------------------------------------------------------------------------
  1544.  
  1545. SW_FUNC void SWStdSpriteColorDrawProc(
  1546.     FramePtr srcFrameP,
  1547.     FramePtr dstFrameP,
  1548.     Rect* srcRect,
  1549.     Rect* dstRect)
  1550. {
  1551.     #pragma unused(dstFrameP)
  1552.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  1553.     
  1554.     if (srcFrameP->maskRgn != NULL)
  1555.     {
  1556.         Rect rgnRect = (**srcFrameP->maskRgn).rgnBBox;
  1557.  
  1558.             // move the mask region to the new sprite location
  1559.         OffsetRgn(srcFrameP->maskRgn,
  1560.             (dstRect->left - (srcRect->left - srcFrameP->frameRect.left) - rgnRect.left) 
  1561.             + srcFrameP->offsetPoint.h,
  1562.             (dstRect->top - (srcRect->top - srcFrameP->frameRect.top) - rgnRect.top)
  1563.             + srcFrameP->offsetPoint.v);
  1564.     }
  1565.     
  1566.     RGBBackColor(&gSWCurrentSpriteBeingDrawn->colorRGB);
  1567.     EraseRgn(srcFrameP->maskRgn);
  1568.     BackColor(whiteColor);
  1569. }
  1570.  
  1571.  
  1572. ///--------------------------------------------------------------------------------------
  1573. //  SWTempSpriteMoveProc - this is installed as the Sprite's MoveProc when the Sprite is
  1574. //    first created. When this is called, it replaces itself with the real MoveProc. This
  1575. //    ensures that the Sprite is drawn in its original position before it is moved by
  1576. //    SWProcessSpriteWorld.
  1577. ///--------------------------------------------------------------------------------------
  1578.  
  1579. SW_FUNC void SWTempSpriteMoveProc(SpritePtr srcSpriteP)
  1580. {
  1581.         // Change the moveProc to the real one. This TempSpriteMoveProc
  1582.         // will never be called for this Sprite again.
  1583.     srcSpriteP->spriteMoveProc = srcSpriteP->realSpriteMoveProc;
  1584.     
  1585.         // If the Sprite has already been drawn, call its real MoveProc.
  1586.         // (We can go ahead and move it since it has been drawn in its original location.)
  1587.     if (srcSpriteP->needsToBeDrawn == false)
  1588.     {
  1589.         if (srcSpriteP->realSpriteMoveProc != NULL)
  1590.             (*srcSpriteP->realSpriteMoveProc)(srcSpriteP);
  1591.     }
  1592. }
  1593.  
  1594.  
  1595. #pragma mark -
  1596. ///--------------------------------------------------------------------------------------
  1597. //    SWSetCurrentFrame
  1598. ///--------------------------------------------------------------------------------------
  1599.  
  1600. SW_FUNC OSErr SWSetCurrentFrame(
  1601.     SpritePtr srcSpriteP,
  1602.     FramePtr newFrameP)
  1603. {
  1604.     short        frameIndex = 0;
  1605.     Boolean        foundFrame = false;
  1606.     OSErr        err = noErr;
  1607.     
  1608.     SW_ASSERT(srcSpriteP != NULL && newFrameP != NULL);
  1609.  
  1610.     for (frameIndex = 0; frameIndex < srcSpriteP->numFrames; frameIndex++)
  1611.     {
  1612.         if (srcSpriteP->frameArray[frameIndex] == newFrameP)
  1613.         {
  1614.             SWSetCurrentFrameIndex(srcSpriteP, frameIndex);
  1615.             foundFrame = true;
  1616.             break;
  1617.         }
  1618.     }
  1619.     
  1620.     if (foundFrame == false)
  1621.         err = kBadParameterErr;
  1622.     
  1623.     SWSetStickyIfError( err );
  1624.     return err;
  1625. }
  1626.  
  1627.  
  1628. ///--------------------------------------------------------------------------------------
  1629. //    SWSetCurrentFrameIndex
  1630. ///--------------------------------------------------------------------------------------
  1631.  
  1632. SW_FUNC void SWSetCurrentFrameIndex(
  1633.     SpritePtr srcSpriteP,
  1634.     short frameIndex)
  1635. {
  1636.     register FramePtr newFrameP;
  1637.     short horizOffset, vertOffset;
  1638.     
  1639.     SW_ASSERT(srcSpriteP != NULL);
  1640.     SW_ASSERT(frameIndex >= 0);
  1641.  
  1642.     if (frameIndex < srcSpriteP->numFrames)
  1643.     {
  1644.         newFrameP = srcSpriteP->frameArray[frameIndex];
  1645.         
  1646.             // If this is a brand new sprite, it won't have a current frame.
  1647.             // (This is used when calculating the hotSpot offset from old to new frame.)
  1648.         if (srcSpriteP->curFrameP == NULL)
  1649.             srcSpriteP->curFrameP = newFrameP;
  1650.  
  1651.         horizOffset = (srcSpriteP->destFrameRect.left - newFrameP->frameRect.left) +
  1652.                     (srcSpriteP->curFrameP->hotSpotH - newFrameP->hotSpotH);
  1653.         vertOffset = (srcSpriteP->destFrameRect.top - newFrameP->frameRect.top) +
  1654.                     (srcSpriteP->curFrameP->hotSpotV - newFrameP->hotSpotV);
  1655.         
  1656.         srcSpriteP->curFrameP = newFrameP;
  1657.         srcSpriteP->destFrameRect = newFrameP->frameRect;
  1658.  
  1659.         if (srcSpriteP->scaledWidth > 0)
  1660.             srcSpriteP->destFrameRect.right = srcSpriteP->destFrameRect.left + 
  1661.                                                 srcSpriteP->scaledWidth;
  1662.         if (srcSpriteP->scaledHeight > 0)
  1663.             srcSpriteP->destFrameRect.bottom = srcSpriteP->destFrameRect.top + 
  1664.                                                 srcSpriteP->scaledHeight;
  1665.         
  1666.         
  1667.         srcSpriteP->destFrameRect.left += horizOffset;
  1668.         srcSpriteP->destFrameRect.right += horizOffset;
  1669.         srcSpriteP->destFrameRect.top += vertOffset;
  1670.         srcSpriteP->destFrameRect.bottom += vertOffset;
  1671.  
  1672.         srcSpriteP->curFrameIndex = frameIndex;
  1673.  
  1674.         srcSpriteP->needsToBeDrawn = true;
  1675.     }
  1676. }
  1677.  
  1678.  
  1679. ///--------------------------------------------------------------------------------------
  1680. //    SWSetSpriteCollideProc
  1681. ///--------------------------------------------------------------------------------------
  1682.  
  1683. SW_FUNC void SWSetSpriteCollideProc(
  1684.     SpritePtr srcSpriteP,
  1685.     CollideProcPtr collideProc)
  1686. {
  1687.     SW_ASSERT(srcSpriteP != NULL);
  1688.     srcSpriteP->spriteCollideProc = collideProc;
  1689. }
  1690.  
  1691.  
  1692. ///--------------------------------------------------------------------------------------
  1693. //    SWSetSpriteColor
  1694. ///--------------------------------------------------------------------------------------
  1695.  
  1696. SW_FUNC void SWSetSpriteColor(
  1697.     SpritePtr srcSpriteP,
  1698.     RGBColor *color)
  1699. {
  1700.     FramePtr    frameP;
  1701.     
  1702.     frameP = srcSpriteP->curFrameP != NULL ? srcSpriteP->curFrameP : srcSpriteP->frameArray[0];
  1703.  
  1704.     srcSpriteP->colorRGB = *color;
  1705.     srcSpriteP->colorValue = SWGetValueFromColor( frameP, color );
  1706. }
  1707.  
  1708.  
  1709. ///--------------------------------------------------------------------------------------
  1710. //    SWSetSpriteDrawProc
  1711. ///--------------------------------------------------------------------------------------
  1712.  
  1713. SW_FUNC OSErr SWSetSpriteDrawProc(
  1714.     SpritePtr srcSpriteP,
  1715.     DrawProcPtr drawProc)
  1716. {
  1717.     OSErr        err = noErr;
  1718.     FramePtr    headFrameP = NULL;
  1719.     
  1720.     SW_ASSERT(srcSpriteP != NULL && drawProc != NULL);
  1721.  
  1722. #if SW_PPC
  1723.     if (drawProc == BlitPixieCompiledSpriteDrawProc)
  1724.         drawProc = BlitPixieMaskDrawProc;
  1725.     
  1726.     if (drawProc == BlitPixieAllBitRectDrawProc ||
  1727.         drawProc == BlitPixieAllBitMaskDrawProc ||
  1728.         drawProc == BlitPixieAllBitPartialMaskDrawProc)
  1729.     {
  1730.         err = k68kOnlyErr;
  1731.     }
  1732. #endif
  1733.     
  1734.     headFrameP = srcSpriteP->frameArray[0];
  1735.     if ( headFrameP != NULL )
  1736.     {
  1737.         if (headFrameP->frameDepth < 8)
  1738.         {
  1739.             if ( (drawProc == BlitPixieRectDrawProc) ||
  1740.                  (drawProc == BlitPixieMaskDrawProc) ||
  1741.                  (drawProc == BlitPixiePartialMaskDrawProc) ||
  1742.                  (drawProc == BlitPixieRLEDrawProc) ||
  1743.                  (drawProc == BlitPixieCompiledSpriteDrawProc) )
  1744.             {
  1745.                 err = kWrongDepthErr;
  1746.             }
  1747.         }
  1748.     }
  1749.  
  1750.     if (headFrameP->framePort == NULL)
  1751.     {
  1752.         if (     (drawProc == BlitPixieAllBitRectDrawProc) ||
  1753.                 (drawProc == BlitPixieAllBitMaskDrawProc) ||
  1754.                 (drawProc == BlitPixieAllBitPartialMaskDrawProc) ||
  1755.                 (drawProc == BlitPixieRectDrawProc) ||
  1756.                 (drawProc == BlitPixieMaskDrawProc) ||
  1757.                 (drawProc == BlitPixiePartialMaskDrawProc) ||
  1758.                 (drawProc == BlitPixieMaskDrawProc) ||
  1759.                  (drawProc == BlitPixiePartialMaskDrawProc) ||
  1760.                  (drawProc == BlitPixieCompiledSpriteDrawProc)
  1761.             )
  1762.         {
  1763.             err = kWrongMaskErr;
  1764.         }
  1765.     }
  1766.     
  1767.     if (headFrameP->maskPort == NULL)
  1768.     {
  1769.         if (     (drawProc == BlitPixieAllBitMaskDrawProc) ||
  1770.                 (drawProc == BlitPixieAllBitPartialMaskDrawProc) ||
  1771.                 (drawProc == BlitPixieMaskDrawProc) ||
  1772.                  (drawProc == BlitPixiePartialMaskDrawProc) ||
  1773.                  (drawProc == BlitPixieCompiledSpriteDrawProc)
  1774.             )
  1775.         {
  1776.             err = kWrongMaskErr;
  1777.         }
  1778.     }
  1779.     
  1780.     if (drawProc == BlitPixieRLEDrawProc && headFrameP->rleDataH == NULL)
  1781.     {
  1782.         err = kSpriteNotCompiledErr;
  1783.     }
  1784. #if SW_68K
  1785.     else if (drawProc == BlitPixieCompiledSpriteDrawProc && headFrameP->pixCodeH == NULL)
  1786.     {
  1787.         err = kSpriteNotCompiledErr;
  1788.     }
  1789. #endif
  1790.         
  1791.     if ( err == noErr )
  1792.         srcSpriteP->frameDrawProc = drawProc;
  1793.         
  1794.     SWSetStickyIfError( err );
  1795.     return err;
  1796. }
  1797.  
  1798.  
  1799. ///--------------------------------------------------------------------------------------
  1800. //    SWSetSpriteFlippedMode
  1801. ///--------------------------------------------------------------------------------------
  1802.  
  1803. SW_FUNC void SWSetSpriteFlippedMode(
  1804.     SpritePtr srcSpriteP,
  1805.     Boolean flippedHorizontal,
  1806.     Boolean flippedVertical)
  1807. {
  1808.     srcSpriteP->flippedHorizontal = flippedHorizontal;
  1809.     srcSpriteP->flippedVertical = flippedVertical;
  1810. }
  1811.  
  1812.  
  1813. ///--------------------------------------------------------------------------------------
  1814. //    SWSetSpriteFrameAdvance (default value for new Sprites is 1)
  1815. ///--------------------------------------------------------------------------------------
  1816.  
  1817. SW_FUNC void SWSetSpriteFrameAdvance(
  1818.     SpritePtr srcSpriteP,
  1819.     short frameAdvance)
  1820. {
  1821.     SW_ASSERT(srcSpriteP != NULL);
  1822.     srcSpriteP->frameAdvance = frameAdvance;
  1823. }
  1824.  
  1825.  
  1826. ///--------------------------------------------------------------------------------------
  1827. //    SWSetSpriteFrameAdvanceMode
  1828. ///--------------------------------------------------------------------------------------
  1829.  
  1830. SW_FUNC void SWSetSpriteFrameAdvanceMode(
  1831.     SpritePtr srcSpriteP,
  1832.     AdvanceType advanceMode)
  1833. {
  1834.     SW_ASSERT(srcSpriteP != NULL);
  1835.     srcSpriteP->frameAdvanceMode = advanceMode;
  1836. }
  1837.  
  1838.  
  1839. ///--------------------------------------------------------------------------------------
  1840. //    SWSetSpriteFrameRange
  1841. ///--------------------------------------------------------------------------------------
  1842.  
  1843. SW_FUNC void SWSetSpriteFrameRange(
  1844.     SpritePtr srcSpriteP,
  1845.     short firstFrameIndex,
  1846.     short lastFrameIndex)
  1847. {
  1848.     SW_ASSERT(srcSpriteP != NULL);
  1849.     
  1850.     if ( firstFrameIndex < 0 )
  1851.         firstFrameIndex = 0;
  1852.     
  1853.     if ( lastFrameIndex > srcSpriteP->maxFrames - 1 )
  1854.         lastFrameIndex = srcSpriteP->maxFrames - 1;
  1855.     
  1856.     srcSpriteP->firstFrameIndex = firstFrameIndex;
  1857.     srcSpriteP->lastFrameIndex = lastFrameIndex;
  1858.     
  1859.         // Make sure the sprite's curFrameIndex is within the new frame range
  1860.     if (srcSpriteP->curFrameIndex < firstFrameIndex)
  1861.         SWSetCurrentFrameIndex(srcSpriteP, firstFrameIndex);
  1862.     else if (srcSpriteP->curFrameIndex > lastFrameIndex)
  1863.         SWSetCurrentFrameIndex(srcSpriteP, lastFrameIndex);
  1864. }
  1865.  
  1866.  
  1867. ///--------------------------------------------------------------------------------------
  1868. //    SWSetSpriteFrameTime - pass -1 to never change frames (default state for new Sprites),
  1869. //    0 to advance as fast as possible, or a millisecond time interval.
  1870. ///--------------------------------------------------------------------------------------
  1871.  
  1872. SW_FUNC void SWSetSpriteFrameTime(
  1873.     SpritePtr srcSpriteP,
  1874.     long timeInterval)
  1875. {
  1876.     SW_ASSERT(srcSpriteP != NULL);
  1877.     srcSpriteP->frameTimeInterval = timeInterval;
  1878. }
  1879.  
  1880.  
  1881. ///--------------------------------------------------------------------------------------
  1882. //    SWSetSpriteFrameProc
  1883. ///--------------------------------------------------------------------------------------
  1884.  
  1885. SW_FUNC void SWSetSpriteFrameProc(
  1886.     SpritePtr srcSpriteP,
  1887.     FrameProcPtr frameProc)
  1888. {
  1889.     SW_ASSERT(srcSpriteP != NULL);
  1890.     srcSpriteP->frameChangeProc = frameProc;
  1891. }
  1892.  
  1893.  
  1894. ///--------------------------------------------------------------------------------------
  1895. //    SWSetSpriteLocation
  1896. ///--------------------------------------------------------------------------------------
  1897.  
  1898. SW_FUNC void SWSetSpriteLocation(
  1899.     SpritePtr srcSpriteP,
  1900.     short horizLoc,
  1901.     short vertLoc)
  1902. {
  1903.     SW_ASSERT(srcSpriteP != NULL);
  1904.     
  1905.     horizLoc -= srcSpriteP->curFrameP->hotSpotH;
  1906.     vertLoc -= srcSpriteP->curFrameP->hotSpotV;
  1907.     
  1908.     srcSpriteP->destFrameRect.bottom = vertLoc + (srcSpriteP->destFrameRect.bottom - 
  1909.                                                 srcSpriteP->destFrameRect.top);
  1910.     srcSpriteP->destFrameRect.right = horizLoc + (srcSpriteP->destFrameRect.right - 
  1911.                                                 srcSpriteP->destFrameRect.left);
  1912.     srcSpriteP->destFrameRect.top = vertLoc;
  1913.     srcSpriteP->destFrameRect.left = horizLoc;
  1914.  
  1915.     srcSpriteP->deltaFrameRect = srcSpriteP->destFrameRect;
  1916.     srcSpriteP->oldFrameRect = srcSpriteP->destFrameRect;
  1917.     srcSpriteP->needsToBeDrawn = true;
  1918. }
  1919.  
  1920.  
  1921. ///--------------------------------------------------------------------------------------
  1922. //    SWSetSpriteMoveBounds
  1923. ///--------------------------------------------------------------------------------------
  1924.  
  1925. SW_FUNC void SWSetSpriteMoveBounds(
  1926.     SpritePtr srcSpriteP,
  1927.     Rect* moveBoundsRect)
  1928. {
  1929.     SW_ASSERT(srcSpriteP != NULL);
  1930.     srcSpriteP->moveBoundsRect = *moveBoundsRect;
  1931. }
  1932.  
  1933.  
  1934. ///--------------------------------------------------------------------------------------
  1935. //    SWSetSpriteMoveDelta
  1936. ///--------------------------------------------------------------------------------------
  1937.  
  1938. SW_FUNC void SWSetSpriteMoveDelta(
  1939.     SpritePtr srcSpriteP,
  1940.     short horizDelta,
  1941.     short vertDelta)
  1942. {
  1943.     SW_ASSERT(srcSpriteP != NULL);
  1944.     
  1945.         // set sprite’s velocity
  1946.     srcSpriteP->horizMoveDelta = horizDelta;
  1947.     srcSpriteP->vertMoveDelta = vertDelta;
  1948. }
  1949.  
  1950.  
  1951. ///--------------------------------------------------------------------------------------
  1952. //    SWSetSpriteMoveTime
  1953. ///--------------------------------------------------------------------------------------
  1954.  
  1955. SW_FUNC void SWSetSpriteMoveTime(
  1956.     SpritePtr srcSpriteP,
  1957.     long timeInterval)
  1958. {
  1959.     SW_ASSERT(srcSpriteP != NULL);
  1960.     srcSpriteP->moveTimeInterval = timeInterval;
  1961. }
  1962.  
  1963.  
  1964. ///--------------------------------------------------------------------------------------
  1965. //    SWSetSpriteMoveProc
  1966. ///--------------------------------------------------------------------------------------
  1967.  
  1968. SW_FUNC void SWSetSpriteMoveProc(
  1969.     SpritePtr srcSpriteP,
  1970.     MoveProcPtr moveProc)
  1971. {
  1972.     SW_ASSERT(srcSpriteP != NULL);
  1973.     
  1974.     srcSpriteP->realSpriteMoveProc = moveProc;
  1975.     
  1976.         // Set the current MoveProc if it isn't SWTempSpriteMoveProc.
  1977.     if (srcSpriteP->spriteMoveProc != SWTempSpriteMoveProc)
  1978.         srcSpriteP->spriteMoveProc = moveProc;
  1979. }
  1980.  
  1981.  
  1982. ///--------------------------------------------------------------------------------------
  1983. //    SWSetSpriteVisible
  1984. ///--------------------------------------------------------------------------------------
  1985.  
  1986. SW_FUNC void SWSetSpriteVisible(
  1987.     SpritePtr srcSpriteP,
  1988.     Boolean isVisible)
  1989. {
  1990.     SW_ASSERT(srcSpriteP != NULL);
  1991.     srcSpriteP->isVisible = isVisible;
  1992.     srcSpriteP->needsToBeDrawn = true;
  1993.     srcSpriteP->needsToBeErased = !isVisible;
  1994. }
  1995.  
  1996.  
  1997. ///--------------------------------------------------------------------------------------
  1998. //    SWGetSpriteVertLoc
  1999. ///--------------------------------------------------------------------------------------
  2000.  
  2001. SW_FUNC short SWGetSpriteVertLoc(
  2002.     SpritePtr srcSpriteP)
  2003. {
  2004.     return srcSpriteP->destFrameRect.top + srcSpriteP->curFrameP->hotSpotV;
  2005. }
  2006.  
  2007.  
  2008. ///--------------------------------------------------------------------------------------
  2009. //    SWGetSpriteHorizLoc
  2010. ///--------------------------------------------------------------------------------------
  2011.  
  2012. SW_FUNC short SWGetSpriteHorizLoc(
  2013.     SpritePtr srcSpriteP)
  2014. {
  2015.     return srcSpriteP->destFrameRect.left + srcSpriteP->curFrameP->hotSpotH;
  2016. }
  2017.  
  2018.  
  2019. #pragma mark -
  2020. ///--------------------------------------------------------------------------------------
  2021. //    SWMoveSprite
  2022. ///--------------------------------------------------------------------------------------
  2023.  
  2024. SW_FUNC void SWMoveSprite(
  2025.     SpritePtr srcSpriteP,
  2026.     short horizLoc,
  2027.     short vertLoc)
  2028. {
  2029.     SW_ASSERT(srcSpriteP != NULL);
  2030.     
  2031.     horizLoc -= srcSpriteP->curFrameP->hotSpotH;
  2032.     vertLoc -= srcSpriteP->curFrameP->hotSpotV;
  2033.     
  2034.     if ((horizLoc != srcSpriteP->destFrameRect.left) || 
  2035.         (vertLoc != srcSpriteP->destFrameRect.top) )
  2036.     {
  2037.         srcSpriteP->destFrameRect.bottom = vertLoc + (srcSpriteP->destFrameRect.bottom - 
  2038.                                                     srcSpriteP->destFrameRect.top);
  2039.         srcSpriteP->destFrameRect.right = horizLoc + (srcSpriteP->destFrameRect.right - 
  2040.                                                     srcSpriteP->destFrameRect.left);
  2041.         srcSpriteP->destFrameRect.top = vertLoc;
  2042.         srcSpriteP->destFrameRect.left = horizLoc;
  2043.     
  2044.         srcSpriteP->needsToBeDrawn = true;
  2045.     }
  2046. }
  2047.  
  2048.  
  2049. ///--------------------------------------------------------------------------------------
  2050. //    SWOffsetSprite
  2051. ///--------------------------------------------------------------------------------------
  2052.  
  2053. SW_FUNC void SWOffsetSprite(
  2054.     SpritePtr srcSpriteP,
  2055.     short horizOffset,
  2056.     short vertOffset)
  2057. {
  2058.     SW_ASSERT(srcSpriteP != NULL);
  2059.     
  2060.     if ((horizOffset != 0) || (vertOffset != 0))
  2061.     {
  2062.         srcSpriteP->destFrameRect.right += horizOffset;
  2063.         srcSpriteP->destFrameRect.bottom += vertOffset;
  2064.         srcSpriteP->destFrameRect.left += horizOffset;
  2065.         srcSpriteP->destFrameRect.top += vertOffset;
  2066.         
  2067.         srcSpriteP->needsToBeDrawn = true;
  2068.     }
  2069. }
  2070.  
  2071.  
  2072. ///--------------------------------------------------------------------------------------
  2073. //    SWBounceSprite
  2074. ///--------------------------------------------------------------------------------------
  2075.  
  2076. SW_FUNC Boolean SWBounceSprite(
  2077.     SpritePtr srcSpriteP)
  2078. {
  2079.     short    horizOffset, vertOffset;
  2080.     
  2081.     SW_ASSERT(srcSpriteP != NULL);
  2082.  
  2083.         // Hit left side or right side
  2084.     if (srcSpriteP->destFrameRect.left < srcSpriteP->moveBoundsRect.left)
  2085.     {
  2086.         srcSpriteP->horizMoveDelta = -srcSpriteP->horizMoveDelta;
  2087.         horizOffset = (srcSpriteP->moveBoundsRect.left - srcSpriteP->destFrameRect.left) * 2;
  2088.     }
  2089.     else if (srcSpriteP->destFrameRect.right > srcSpriteP->moveBoundsRect.right)
  2090.     {
  2091.         srcSpriteP->horizMoveDelta = -srcSpriteP->horizMoveDelta;
  2092.         horizOffset = (srcSpriteP->moveBoundsRect.right - srcSpriteP->destFrameRect.right) * 2;
  2093.     }
  2094.     else
  2095.         horizOffset = 0;
  2096.  
  2097.  
  2098.         // Hit top or bottom
  2099.     if (srcSpriteP->destFrameRect.top < srcSpriteP->moveBoundsRect.top)
  2100.     {
  2101.         srcSpriteP->vertMoveDelta = -srcSpriteP->vertMoveDelta;
  2102.         vertOffset = (srcSpriteP->moveBoundsRect.top - srcSpriteP->destFrameRect.top) * 2;
  2103.     }
  2104.     else if (srcSpriteP->destFrameRect.bottom > srcSpriteP->moveBoundsRect.bottom)
  2105.     {
  2106.         srcSpriteP->vertMoveDelta = -srcSpriteP->vertMoveDelta;
  2107.         vertOffset = (srcSpriteP->moveBoundsRect.bottom - srcSpriteP->destFrameRect.bottom) * 2;
  2108.     }
  2109.     else
  2110.         vertOffset = 0;
  2111.     
  2112.     
  2113.         // Bounce the sprite if it had a collision with the wall
  2114.     if ((horizOffset != 0) || (vertOffset != 0))
  2115.     {
  2116.         SWOffsetSprite(srcSpriteP, horizOffset, vertOffset);
  2117.         return true;
  2118.     }
  2119.     else
  2120.     {
  2121.         return false;
  2122.     }
  2123. }
  2124.  
  2125.  
  2126. ///--------------------------------------------------------------------------------------
  2127. //    SWWrapSprite
  2128. ///--------------------------------------------------------------------------------------
  2129.  
  2130. SW_FUNC Boolean SWWrapSprite(
  2131.     SpritePtr srcSpriteP)
  2132. {
  2133.     short    horizOffset, vertOffset;
  2134.     
  2135.     SW_ASSERT(srcSpriteP != NULL);
  2136.     
  2137.         // Wrap to left or right
  2138.     if (srcSpriteP->oldFrameRect.left > srcSpriteP->moveBoundsRect.right)
  2139.     {
  2140.         horizOffset = - ((srcSpriteP->moveBoundsRect.right -
  2141.                         srcSpriteP->moveBoundsRect.left) +
  2142.                         (srcSpriteP->destFrameRect.right - 
  2143.                         srcSpriteP->destFrameRect.left) + srcSpriteP->horizMoveDelta);
  2144.     }
  2145.     else if (srcSpriteP->oldFrameRect.right < srcSpriteP->moveBoundsRect.left)
  2146.     {
  2147.         horizOffset = (srcSpriteP->moveBoundsRect.right -
  2148.                         srcSpriteP->moveBoundsRect.left) +
  2149.                         (srcSpriteP->destFrameRect.right - 
  2150.                         srcSpriteP->destFrameRect.left) - srcSpriteP->horizMoveDelta;
  2151.     }
  2152.     else
  2153.         horizOffset = 0;
  2154.     
  2155.     
  2156.         // Wrap to top or bottom
  2157.     if (srcSpriteP->oldFrameRect.top > srcSpriteP->moveBoundsRect.bottom)
  2158.     {
  2159.         vertOffset = -((srcSpriteP->moveBoundsRect.bottom -
  2160.                             srcSpriteP->moveBoundsRect.top) +
  2161.                             (srcSpriteP->destFrameRect.bottom - 
  2162.                             srcSpriteP->destFrameRect.top) + srcSpriteP->vertMoveDelta);
  2163.     }
  2164.     else if (srcSpriteP->oldFrameRect.bottom < srcSpriteP->moveBoundsRect.top)
  2165.     {
  2166.         vertOffset = (srcSpriteP->moveBoundsRect.bottom -
  2167.                             srcSpriteP->moveBoundsRect.top) +
  2168.                             (srcSpriteP->destFrameRect.bottom - 
  2169.                             srcSpriteP->destFrameRect.top) - srcSpriteP->vertMoveDelta;
  2170.     }
  2171.     else
  2172.         vertOffset = 0;
  2173.     
  2174.     
  2175.         // Wrap sprite, and set delta and old rects to current rect
  2176.     if ((horizOffset != 0) || (vertOffset != 0))
  2177.     {
  2178.         SWOffsetSprite(srcSpriteP, horizOffset, vertOffset);
  2179.         
  2180.         srcSpriteP->deltaFrameRect = srcSpriteP->destFrameRect;
  2181.         srcSpriteP->oldFrameRect = srcSpriteP->destFrameRect;
  2182.         
  2183.         return true;
  2184.     }
  2185.     else
  2186.     {
  2187.         return false;
  2188.     }
  2189. }
  2190.  
  2191.  
  2192. ///--------------------------------------------------------------------------------------
  2193. //    SWRegionCollision
  2194. ///--------------------------------------------------------------------------------------
  2195.  
  2196. SW_FUNC Boolean SWRegionCollision(
  2197.     SpritePtr srcSpriteP,
  2198.     SpritePtr dstSpriteP)
  2199. {
  2200.     Rect                 rgnRect;
  2201.  
  2202.      SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
  2203.      SW_ASSERT(srcSpriteP->curFrameP->maskRgn != NULL);
  2204.      SW_ASSERT(dstSpriteP->curFrameP->maskRgn != NULL);
  2205.  
  2206.         // copy one of the regions in case they're the same 
  2207.         // (would happen if the sprites are clones using the same frame)
  2208.     CopyRgn( dstSpriteP->curFrameP->maskRgn, gSWCollisionSpareRgn );
  2209.     
  2210.     rgnRect = (**srcSpriteP->curFrameP->maskRgn).rgnBBox;
  2211.  
  2212.         // move the mask region to the new sprite location
  2213.     OffsetRgn(srcSpriteP->curFrameP->maskRgn,
  2214.                 (srcSpriteP->destFrameRect.left - rgnRect.left) +
  2215.                 srcSpriteP->curFrameP->offsetPoint.h,
  2216.                 (srcSpriteP->destFrameRect.top - rgnRect.top) +
  2217.                 srcSpriteP->curFrameP->offsetPoint.v);
  2218.  
  2219.     rgnRect = (**gSWCollisionSpareRgn).rgnBBox;
  2220.  
  2221.         // move the mask region to the new sprite location
  2222.     OffsetRgn(gSWCollisionSpareRgn,
  2223.                 (dstSpriteP->destFrameRect.left - rgnRect.left) +
  2224.                 dstSpriteP->curFrameP->offsetPoint.h,
  2225.                 (dstSpriteP->destFrameRect.top - rgnRect.top) +
  2226.                 dstSpriteP->curFrameP->offsetPoint.v);
  2227.  
  2228.     SectRgn(srcSpriteP->curFrameP->maskRgn, gSWCollisionSpareRgn, gSWCollisionSectRgn);
  2229.  
  2230.     return (!EmptyRgn(gSWCollisionSectRgn));
  2231. }
  2232.  
  2233.  
  2234. ///--------------------------------------------------------------------------------------
  2235. //    SWRadiusCollision
  2236. ///--------------------------------------------------------------------------------------
  2237.  
  2238. SW_FUNC Boolean SWRadiusCollision(
  2239.     SpritePtr srcSpriteP,
  2240.     SpritePtr dstSpriteP)
  2241. {
  2242.     Point                 centerOne, centerTwo;
  2243.     register short        radiusOne, radiusTwo;
  2244.     register short        horizDistance, vertDistance;
  2245.     
  2246.     SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
  2247.  
  2248.         // get radii - - assumes circular sprites!
  2249.     radiusOne = (srcSpriteP->destFrameRect.right-srcSpriteP->destFrameRect.left)/2;
  2250.     radiusTwo = (dstSpriteP->destFrameRect.right-dstSpriteP->destFrameRect.left)/2;
  2251.     
  2252.         // find centers
  2253.     centerOne.h = srcSpriteP->destFrameRect.left + radiusOne;
  2254.     centerOne.v = srcSpriteP->destFrameRect.top + radiusOne;
  2255.     centerTwo.h = dstSpriteP->destFrameRect.left + radiusTwo;
  2256.     centerTwo.v = dstSpriteP->destFrameRect.top + radiusTwo;
  2257.                     
  2258.     horizDistance = centerOne.h - centerTwo.h;
  2259.     vertDistance = centerOne.v - centerTwo.v;
  2260.  
  2261.     return ( (horizDistance*horizDistance) + (vertDistance*vertDistance) <
  2262.         ((radiusOne+radiusTwo)*(radiusOne+radiusTwo)) );
  2263. }
  2264.  
  2265.  
  2266. ///--------------------------------------------------------------------------------------
  2267. //    SWPixelCollision
  2268. ///--------------------------------------------------------------------------------------
  2269.  
  2270. SW_FUNC Boolean SWPixelCollision(
  2271.     SpritePtr srcSpriteP,
  2272.     SpritePtr dstSpriteP)
  2273. {
  2274.     Boolean            collision;
  2275.     Rect            sectRect;
  2276.     Rect            srcSectRect;
  2277.     Rect            dstSectRect;
  2278.     FramePtr        srcFrameP,
  2279.                     dstFrameP;
  2280.  
  2281.     SW_ASSERT(srcSpriteP != NULL);
  2282.     SW_ASSERT(dstSpriteP != NULL);
  2283.      SW_ASSERT(srcSpriteP->curFrameP->maskPort != NULL);
  2284.      SW_ASSERT(dstSpriteP->curFrameP->maskPort != NULL);
  2285.      SW_ASSERT(srcSpriteP->curFrameP->isFrameLocked);
  2286.      SW_ASSERT(dstSpriteP->curFrameP->isFrameLocked);
  2287.     SW_ASSERT(dstSpriteP->curFrameP->frameDepth >= 8);
  2288.      SW_ASSERT(srcSpriteP->curFrameP->frameDepth == dstSpriteP->curFrameP->frameDepth);
  2289.  
  2290.         // calculate intersection rect in spriteworld
  2291.     sectRect.left = SW_MAX(srcSpriteP->destFrameRect.left, dstSpriteP->destFrameRect.left);
  2292.     sectRect.top = SW_MAX(srcSpriteP->destFrameRect.top, dstSpriteP->destFrameRect.top);
  2293.     sectRect.right = SW_MIN(srcSpriteP->destFrameRect.right, dstSpriteP->destFrameRect.right);
  2294.     sectRect.bottom = SW_MIN(srcSpriteP->destFrameRect.bottom, dstSpriteP->destFrameRect.bottom);
  2295.     
  2296.     if ( sectRect.right > sectRect.left && sectRect.bottom > sectRect.top )
  2297.     {
  2298.         srcFrameP = srcSpriteP->curFrameP;
  2299.         dstFrameP = dstSpriteP->curFrameP;
  2300.         
  2301.             // calculate sectRect in source frame
  2302.         srcSectRect.left = srcFrameP->frameRect.left + (sectRect.left-srcSpriteP->destFrameRect.left);
  2303.         srcSectRect.top = srcFrameP->frameRect.top + (sectRect.top-srcSpriteP->destFrameRect.top);
  2304.         srcSectRect.right = srcFrameP->frameRect.left + (sectRect.right-srcSpriteP->destFrameRect.left);
  2305.         srcSectRect.bottom = srcFrameP->frameRect.top +(sectRect.bottom-srcSpriteP->destFrameRect.top);
  2306.     
  2307.             // calculate sectRect in dest frame
  2308.         dstSectRect.left = dstFrameP->frameRect.left + (sectRect.left-dstSpriteP->destFrameRect.left);
  2309.         dstSectRect.top = dstFrameP->frameRect.top +(sectRect.top-dstSpriteP->destFrameRect.top);
  2310.         dstSectRect.right = dstFrameP->frameRect.left + (sectRect.right-dstSpriteP->destFrameRect.left);
  2311.         dstSectRect.bottom = dstFrameP->frameRect.top +(sectRect.bottom-dstSpriteP->destFrameRect.top);
  2312.     
  2313.         collision = BlitPixieMaskCollisionProc(srcSpriteP, dstSpriteP, &srcSectRect, &dstSectRect );
  2314.     }
  2315.     else
  2316.         collision = false;
  2317.  
  2318.     return collision;
  2319. }
  2320.  
  2321.  
  2322. ///--------------------------------------------------------------------------------------
  2323. //    SWRLECollision
  2324. ///--------------------------------------------------------------------------------------
  2325.  
  2326. SW_FUNC Boolean SWRLECollision(
  2327.     SpritePtr srcSpriteP,
  2328.     SpritePtr dstSpriteP)
  2329. {
  2330.     Boolean            collision;
  2331.     Rect            sectRect;
  2332.     Rect            srcSectRect;
  2333.     Rect            dstSectRect;
  2334.     FramePtr        srcFrameP,
  2335.                     dstFrameP;
  2336.     
  2337.     SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
  2338.      SW_ASSERT(srcSpriteP->curFrameP->rleDataH != NULL);
  2339.      SW_ASSERT(dstSpriteP->curFrameP->rleDataH != NULL);
  2340.      SW_ASSERT(srcSpriteP->curFrameP->isFrameLocked);
  2341.      SW_ASSERT(dstSpriteP->curFrameP->isFrameLocked);
  2342.         
  2343.         // calculate intersection rect in spriteworld
  2344.     sectRect.left = SW_MAX(srcSpriteP->destFrameRect.left, dstSpriteP->destFrameRect.left);
  2345.     sectRect.top = SW_MAX(srcSpriteP->destFrameRect.top, dstSpriteP->destFrameRect.top);
  2346.     sectRect.right = SW_MIN(srcSpriteP->destFrameRect.right, dstSpriteP->destFrameRect.right);
  2347.     sectRect.bottom = SW_MIN(srcSpriteP->destFrameRect.bottom, dstSpriteP->destFrameRect.bottom);
  2348.     
  2349.     if ( sectRect.right > sectRect.left && sectRect.bottom > sectRect.top )
  2350.     {
  2351.         srcFrameP = srcSpriteP->curFrameP;
  2352.         dstFrameP = dstSpriteP->curFrameP;
  2353.         
  2354.             // calculate sectRect in source frame local coords
  2355.         srcSectRect.left = (sectRect.left-srcSpriteP->destFrameRect.left);
  2356.         srcSectRect.top = (sectRect.top-srcSpriteP->destFrameRect.top);
  2357.         srcSectRect.right = (sectRect.right-srcSpriteP->destFrameRect.left);
  2358.         srcSectRect.bottom = (sectRect.bottom-srcSpriteP->destFrameRect.top);
  2359.     
  2360.             // calculate sectRect in dest frame local coords
  2361.         dstSectRect.left = (sectRect.left-dstSpriteP->destFrameRect.left);
  2362.         dstSectRect.top = (sectRect.top-dstSpriteP->destFrameRect.top);
  2363.         dstSectRect.right = (sectRect.right-dstSpriteP->destFrameRect.left);
  2364.         dstSectRect.bottom = (sectRect.bottom-dstSpriteP->destFrameRect.top);
  2365.     
  2366.         collision = BlitPixieRLECollisionProc(srcSpriteP, dstSpriteP, &srcSectRect, &dstSectRect );
  2367.     }
  2368.     else
  2369.         collision = false;
  2370.  
  2371.     return collision;
  2372. }
  2373.  
  2374.  
  2375. ///--------------------------------------------------------------------------------------
  2376. //    SWIsSpriteInRect
  2377. ///--------------------------------------------------------------------------------------
  2378.  
  2379. SW_FUNC Boolean SWIsSpriteInRect(
  2380.     SpritePtr srcSpriteP,
  2381.     Rect* testRect)
  2382. {
  2383.     SW_ASSERT(srcSpriteP != NULL);
  2384.     
  2385.     return ((SW_COLLISION_RECT_TOP(srcSpriteP) < testRect->bottom) &&
  2386.             (SW_COLLISION_RECT_BOTTOM(srcSpriteP) > testRect->top) &&
  2387.              (SW_COLLISION_RECT_LEFT(srcSpriteP) < testRect->right) &&
  2388.              (SW_COLLISION_RECT_RIGHT(srcSpriteP) > testRect->left));
  2389. }
  2390.  
  2391.  
  2392. ///--------------------------------------------------------------------------------------
  2393. //    SWIsSpriteFullyInRect
  2394. ///--------------------------------------------------------------------------------------
  2395.  
  2396. SW_FUNC Boolean SWIsSpriteFullyInRect(
  2397.     SpritePtr srcSpriteP,
  2398.     Rect* testRect)
  2399. {
  2400.     SW_ASSERT(srcSpriteP != NULL);
  2401.     
  2402.     return ((SW_COLLISION_RECT_TOP(srcSpriteP) >= testRect->top) &&
  2403.             (SW_COLLISION_RECT_BOTTOM(srcSpriteP) <= testRect->bottom) &&
  2404.              (SW_COLLISION_RECT_LEFT(srcSpriteP) >= testRect->left) &&
  2405.              (SW_COLLISION_RECT_RIGHT(srcSpriteP) <= testRect->right));
  2406. }
  2407.  
  2408.  
  2409. ///--------------------------------------------------------------------------------------
  2410. //    SWIsPointInSprite
  2411. ///--------------------------------------------------------------------------------------
  2412.  
  2413. SW_FUNC Boolean SWIsPointInSprite(
  2414.     SpritePtr srcSpriteP,
  2415.     Point testPoint)
  2416. {
  2417.     SW_ASSERT(srcSpriteP != NULL);
  2418.     
  2419.     return    (testPoint.h >= SW_COLLISION_RECT_LEFT(srcSpriteP)) &&
  2420.             (testPoint.h < SW_COLLISION_RECT_RIGHT(srcSpriteP)) &&
  2421.             (testPoint.v >= SW_COLLISION_RECT_TOP(srcSpriteP)) &&
  2422.             (testPoint.v < SW_COLLISION_RECT_BOTTOM(srcSpriteP));
  2423. }
  2424.  
  2425.